Deployment with Configuration
- {showPagination && (
+ {showPagination && !areFilteredRowsLoading && (
)}
diff --git a/src/Shared/Components/Table/styles.scss b/src/Shared/Components/Table/styles.scss
index 2df9df9aa..ed2fb7c1e 100644
--- a/src/Shared/Components/Table/styles.scss
+++ b/src/Shared/Components/Table/styles.scss
@@ -61,6 +61,10 @@
}
&__row {
+ & &__hover-item {
+ display: none;
+ }
+
&:focus {
outline: none;
}
@@ -83,6 +87,13 @@
&--bulk-selected.generic-table__row--active > * {
background-color: var(--B100);
}
+
+ &:hover,
+ &--active {
+ .generic-table__row__hover-item {
+ display: inherit;
+ }
+ }
}
.sortable-table-header__resize-btn:hover,
diff --git a/src/Shared/Components/Table/types.ts b/src/Shared/Components/Table/types.ts
index f7ece4cce..e4faa7a64 100644
--- a/src/Shared/Components/Table/types.ts
+++ b/src/Shared/Components/Table/types.ts
@@ -23,7 +23,7 @@ import {
UseUrlFiltersProps,
UseUrlFiltersReturnType,
} from '@Common/Hooks'
-import { GenericEmptyStateType } from '@Common/index'
+import { APIOptions, GenericEmptyStateType } from '@Common/index'
import { PageSizeOption } from '@Common/Pagination/types'
import { SortableTableHeaderCellProps, useResizableTableConfig } from '@Common/SortableTableHeaderCell'
@@ -209,7 +209,7 @@ export type ViewWrapperProps<
? {}
: Pick<
UseFiltersReturnType,
- 'offset' | 'handleSearch' | 'searchKey' | 'sortBy' | 'sortOrder' | 'clearFilters'
+ 'offset' | 'handleSearch' | 'searchKey' | 'sortBy' | 'sortOrder' | 'clearFilters' | 'areFiltersApplied'
>) &
AdditionalProps &
Partial
> & {
@@ -317,7 +317,10 @@ export type InternalTableProps<
| {
rows?: never
/** NOTE: Sorting on frontend is only handled if rows is provided instead of getRows */
- getRows: (props: GetRowsProps) => Promise>
+ getRows: (
+ props: GetRowsProps,
+ abortControllerRef: APIOptions['abortControllerRef'],
+ ) => Promise<{ rows: RowsType; totalRows: number }>
}
) &
(
@@ -427,7 +430,9 @@ export interface TableContentProps<
| 'paginationVariant'
| 'RowActionsOnHoverComponent'
| 'pageSizeOptions'
+ | 'getRows'
> {
filteredRows: RowsType
areFilteredRowsLoading: boolean
+ totalRows: number
}
diff --git a/src/Shared/Components/Table/utils.ts b/src/Shared/Components/Table/utils.ts
index d0c3f6d14..8e9ff9580 100644
--- a/src/Shared/Components/Table/utils.ts
+++ b/src/Shared/Components/Table/utils.ts
@@ -43,17 +43,21 @@ export const searchAndSortRows = <
filter: TableProps['filter'],
filterData: UseFiltersReturnType,
comparator?: Column['comparator'],
-) => {
+): Awaited['getRows']>> => {
const { sortBy, sortOrder } = filterData ?? {}
const filteredRows = filter ? rows.filter((row) => filter(row, filterData)) : rows
- return comparator && sortBy
- ? filteredRows.sort(
- (rowA, rowB) =>
- (sortOrder === SortingOrder.ASC ? 1 : -1) * comparator(rowA.data[sortBy], rowB.data[sortBy]),
- )
- : filteredRows
+ return {
+ rows:
+ comparator && sortBy
+ ? filteredRows.sort(
+ (rowA, rowB) =>
+ (sortOrder === SortingOrder.ASC ? 1 : -1) * comparator(rowA.data[sortBy], rowB.data[sortBy]),
+ )
+ : filteredRows,
+ totalRows: filteredRows.length,
+ }
}
export const getVisibleColumnsFromLocalStorage = <
@@ -199,5 +203,5 @@ export const scrollToShowActiveElementIfNeeded = (
scrollTop += bottom - parentBottom
}
- parent.scrollTo({ top: scrollTop, behavior: 'smooth' })
+ parent.scrollTo({ top: scrollTop, behavior: 'auto' })
}
diff --git a/src/Shared/Services/ToastManager/ToastContent.tsx b/src/Shared/Services/ToastManager/ToastContent.tsx
index 2e9ce70a5..7ae0705d8 100644
--- a/src/Shared/Services/ToastManager/ToastContent.tsx
+++ b/src/Shared/Services/ToastManager/ToastContent.tsx
@@ -17,7 +17,7 @@
import { Button, ButtonStyleType, ButtonVariantType } from '@Shared/Components'
import { ComponentSizeType } from '@Shared/constants'
-import { ToastProps } from './types'
+import { ShortcutToastContentProps, ToastProps } from './types'
export const ToastContent = ({
title,
@@ -39,3 +39,17 @@ export const ToastContent = ({
)}
)
+
+export const ShortcutToastContent = ({ shortcuts, text }: ShortcutToastContentProps) => (
+
+ {shortcuts.map((shortcutKey) => (
+
+ {shortcutKey}
+
+ ))}
+ {text}
+
+)
diff --git a/src/Shared/Services/ToastManager/constants.tsx b/src/Shared/Services/ToastManager/constants.tsx
index 6d9a23758..0310c041e 100644
--- a/src/Shared/Services/ToastManager/constants.tsx
+++ b/src/Shared/Services/ToastManager/constants.tsx
@@ -26,7 +26,7 @@ import { ReactComponent as ICWarning } from '@Icons/ic-warning.svg'
import { Button, ButtonStyleType, ButtonVariantType } from '@Shared/Components'
import { ALLOW_ACTION_OUTSIDE_FOCUS_TRAP, ComponentSizeType } from '@Shared/constants'
-import { ToastProps, ToastVariantType } from './types'
+import { BaseToastProps, ToastProps, ToastVariantType } from './types'
export const TOAST_BASE_CONFIG: ToastContainerProps = {
autoClose: 5000,
@@ -55,7 +55,7 @@ export const TOAST_BASE_CONFIG: ToastContainerProps = {
}
export const TOAST_VARIANT_TO_CONFIG_MAP: Record<
- ToastVariantType,
+ BaseToastProps['variant'],
Required
> & Pick
> = {
[ToastVariantType.info]: {
diff --git a/src/Shared/Services/ToastManager/toastManager.scss b/src/Shared/Services/ToastManager/toastManager.scss
index 4a44a59bb..8ad85df33 100644
--- a/src/Shared/Services/ToastManager/toastManager.scss
+++ b/src/Shared/Services/ToastManager/toastManager.scss
@@ -98,3 +98,15 @@
}
}
}
+
+div.shortcut-toast {
+ background: transparent;
+ border-radius: 12px;
+ display: flex;
+ margin: 0;
+ min-height: 0;
+ padding: 0;
+ box-shadow: none;
+ align-items: center;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/src/Shared/Services/ToastManager/toastManager.service.tsx b/src/Shared/Services/ToastManager/toastManager.service.tsx
index 3b32d585e..5d3e3c215 100644
--- a/src/Shared/Services/ToastManager/toastManager.service.tsx
+++ b/src/Shared/Services/ToastManager/toastManager.service.tsx
@@ -18,7 +18,7 @@
import { toast, ToastContainer, ToastOptions } from 'react-toastify'
import { TOAST_BASE_CONFIG, TOAST_VARIANT_TO_CONFIG_MAP } from './constants'
-import { ToastContent } from './ToastContent'
+import { ShortcutToastContent, ToastContent } from './ToastContent'
import { ToastProps, ToastVariantType } from './types'
import './toastManager.scss'
@@ -106,9 +106,23 @@ class ToastManager {
description,
buttonProps,
progressBarBg: customProgressBarBg,
+ text,
+ shortcuts,
}: ToastProps,
options: Pick = {},
) => {
+ if (variant === ToastVariantType.shortcut) {
+ return toast(, {
+ position: 'top-center',
+ containerId: 'devtron-shortcut-toast',
+ className: 'shortcut-toast',
+ hideProgressBar: true,
+ closeButton: false,
+ autoClose: 3000,
+ closeOnClick: true,
+ })
+ }
+
const { icon, type, title: defaultTitle, progressBarBg } = TOAST_VARIANT_TO_CONFIG_MAP[variant]
return toast(
diff --git a/src/Shared/Services/ToastManager/types.ts b/src/Shared/Services/ToastManager/types.ts
index 4413f7759..ed2d891d6 100644
--- a/src/Shared/Services/ToastManager/types.ts
+++ b/src/Shared/Services/ToastManager/types.ts
@@ -16,6 +16,7 @@
import { ReactElement } from 'react'
+import { SupportedKeyboardKeysType } from '@Common/Hooks'
import { ButtonComponentType, ButtonProps } from '@Shared/Components'
export enum ToastVariantType {
@@ -24,9 +25,24 @@ export enum ToastVariantType {
error = 'error',
warn = 'warn',
notAuthorized = 'notAuthorized',
+ shortcut = 'shortcut',
}
-export interface ToastProps {
+export interface ShortcutToastProps {
+ variant: ToastVariantType.shortcut
+ /**
+ * Text to display along the shortcuts in the toast
+ * Example: "Press [S] to switch context"
+ */
+ text: string
+ /**
+ * The shortcuts to be displayed in the toast
+ * Note: The shortcuts should be in the format of `['Ctrl', 'A']
+ */
+ shortcuts: SupportedKeyboardKeysType[]
+}
+
+export interface BaseToastProps {
/**
* Title for the toast
* If not provided, defaults to a value based on the selected variant
@@ -45,7 +61,7 @@ export interface ToastProps {
*
* @default ToastVariantType.info
*/
- variant?: ToastVariantType
+ variant?: Exclude
/**
* Props for the action button to be displayed in the toast
*
@@ -57,3 +73,12 @@ export interface ToastProps {
*/
progressBarBg?: string
}
+
+export type ToastProps =
+ | (BaseToastProps & Partial, never>>)
+ | (ShortcutToastProps & Partial, never>>)
+
+export interface ShortcutToastContentProps {
+ text: string
+ shortcuts: SupportedKeyboardKeysType[]
+}
diff --git a/src/Shared/Services/app.service.ts b/src/Shared/Services/app.service.ts
index 7be3abbff..50964de93 100644
--- a/src/Shared/Services/app.service.ts
+++ b/src/Shared/Services/app.service.ts
@@ -16,47 +16,23 @@
import { AppConfigProps, GetTemplateAPIRouteType } from '@Pages/index'
-import { get, getUrlWithSearchParams, ResponseType, ROUTES, showError } from '../../Common'
+import { get, getUrlWithSearchParams, ResponseType, ROUTES } from '../../Common'
import { getTemplateAPIRoute } from '..'
import {
AppEnvDeploymentConfigDTO,
AppEnvDeploymentConfigPayloadType,
CIMaterialInfoDTO,
- CIMaterialInfoType,
GetCITriggerInfoParamsType,
} from './app.types'
-import { getParsedCIMaterialInfo } from './utils'
-export const getCITriggerInfo = async (params: GetCITriggerInfoParamsType): Promise => {
- try {
- const { result } = (await get(
- `${ROUTES.APP}/material-info/${params.envId}/${params.ciArtifactId}`,
- )) as ResponseType
-
- return getParsedCIMaterialInfo(result)
- } catch (err) {
- showError(err)
- throw err
- }
-}
+export const getCITriggerInfo = async (params: GetCITriggerInfoParamsType) =>
+ get(`${ROUTES.APP}/material-info/${params.envId}/${params.ciArtifactId}`)
/**
* The only difference between this and getCITriggerInfo is it doesn't have env and trigger related meta info
*/
-export const getArtifactInfo = async (
- params: Pick,
-): Promise => {
- try {
- const { result } = (await get(
- `${ROUTES.APP}/material-info/${params.ciArtifactId}`,
- )) as ResponseType
-
- return getParsedCIMaterialInfo(result)
- } catch (err) {
- showError(err)
- throw err
- }
-}
+export const getArtifactInfo = (params: Pick) =>
+ get(`${ROUTES.APP}/material-info/${params.ciArtifactId}`)
export const getAppEnvDeploymentConfig = ({
params,