diff --git a/package-lock.json b/package-lock.json
index 297fadd1c..3f402a30e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@devtron-labs/devtron-fe-common-lib",
- "version": "1.14.0",
+ "version": "1.14.0-pre-0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@devtron-labs/devtron-fe-common-lib",
- "version": "1.14.0",
+ "version": "1.14.0-pre-0",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
diff --git a/package.json b/package.json
index 198fe2859..733ca4fa2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@devtron-labs/devtron-fe-common-lib",
- "version": "1.14.0",
+ "version": "1.14.0-pre-0",
"description": "Supporting common component library",
"type": "module",
"main": "dist/index.js",
diff --git a/src/Assets/IconV2/ic-app-template.svg b/src/Assets/IconV2/ic-app-template.svg
new file mode 100644
index 000000000..70a64cf7a
--- /dev/null
+++ b/src/Assets/IconV2/ic-app-template.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/src/Assets/IconV2/ic-devtron-app.svg b/src/Assets/IconV2/ic-devtron-app.svg
new file mode 100644
index 000000000..adc694a17
--- /dev/null
+++ b/src/Assets/IconV2/ic-devtron-app.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/src/Assets/IconV2/ic-devtron-job.svg b/src/Assets/IconV2/ic-devtron-job.svg
new file mode 100644
index 000000000..d5a2bc1bd
--- /dev/null
+++ b/src/Assets/IconV2/ic-devtron-job.svg
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/src/Assets/Img/empty-create.png b/src/Assets/Img/empty-create.png
new file mode 100755
index 000000000..705f13dd7
Binary files /dev/null and b/src/Assets/Img/empty-create.png differ
diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts
index 49ce89f06..3243f76c2 100644
--- a/src/Common/Constants.ts
+++ b/src/Common/Constants.ts
@@ -22,16 +22,6 @@ export const DEVTRON_HOME_PAGE = 'https://devtron.ai/'
export const DOCUMENTATION_VERSION = '/v/v0.7'
export const DISCORD_LINK = 'https://discord.devtron.ai/'
export const DEFAULT_JSON_SCHEMA_URI = 'https://json-schema.org/draft/2020-12/schema'
-export const DOCUMENTATION = {
- APP_METRICS: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/applications/app-details/app-metrics`,
- APP_TAGS: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/applications/create-application#tags`,
- APP_OVERVIEW_TAGS: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/applications/overview#manage-tags`,
- BLOB_STORAGE: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/getting-started/install/installation-configuration#configuration-of-blob-storage`,
- GLOBAL_CONFIG_BUILD_INFRA: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/global-configurations/build-infra`,
- ENTERPRISE_LICENSE: `${DOCUMENTATION_HOME_PAGE}/enterprise-license`,
- KUBE_CONFIG: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/resource-browser#running-kubectl-commands-locally`,
- TENANT_INSTALLATION: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/software-distribution-hub/tenants`,
-}
export const PATTERNS = {
STRING: /^[a-zA-Z0-9_]+$/,
diff --git a/src/Common/CustomTagSelector/PropagateTagInfo.tsx b/src/Common/CustomTagSelector/PropagateTagInfo.tsx
index e15f2d119..d09e6739b 100644
--- a/src/Common/CustomTagSelector/PropagateTagInfo.tsx
+++ b/src/Common/CustomTagSelector/PropagateTagInfo.tsx
@@ -14,12 +14,10 @@
* limitations under the License.
*/
-import React from 'react'
import { ReactComponent as InjectTag } from '../../Assets/Icon/inject-tag.svg'
import { ReactComponent as ICHelpOutline } from '../../Assets/Icon/ic-help-outline.svg'
import { TippyCustomized } from '../TippyCustomized'
import { TippyTheme } from '../Types'
-import { DOCUMENTATION } from '../Constants'
export default function PropagateTagInfo({ isCreateApp }: { isCreateApp: boolean }) {
const additionalInfo = () => (
@@ -47,7 +45,7 @@ export default function PropagateTagInfo({ isCreateApp }: { isCreateApp: boolean
showCloseButton
trigger="click"
interactive
- documentationLink={isCreateApp ? DOCUMENTATION.APP_TAGS : DOCUMENTATION.APP_OVERVIEW_TAGS}
+ documentationLink={isCreateApp ? "APP_TAGS" : "APP_OVERVIEW_TAGS"}
documentationLinkText="View Documentation"
>
diff --git a/src/Common/TippyCustomized.tsx b/src/Common/TippyCustomized.tsx
index fbfaa4ec9..32ec5bbb3 100644
--- a/src/Common/TippyCustomized.tsx
+++ b/src/Common/TippyCustomized.tsx
@@ -19,15 +19,15 @@ import Tippy from '@tippyjs/react'
import { ReactComponent as CloseIcon } from '../Assets/Icon/ic-cross.svg'
import { ReactComponent as Help } from '../Assets/Icon/ic-help.svg'
import { ReactComponent as ICHelpOutline } from '../Assets/Icon/ic-help-outline.svg'
-import { ReactComponent as ICOpenInNew } from '../Assets/Icon/ic-open-in-new.svg'
import 'tippy.js/animations/shift-toward-subtle.css'
import 'tippy.js/animations/shift-toward.css'
import { TippyCustomizedProps, TippyTheme } from './Types'
import { not, stopPropagation } from './Helper'
+import { DocLink } from '../Shared/DocLink'
// This component will handle some of the new tippy designs and interactions
// So this can be updated to support further for new features or interactions
-export const TippyCustomized = (props: TippyCustomizedProps) => {
+export const TippyCustomized =
(props: TippyCustomizedProps) => {
const tippyRef = useRef(null)
const [showHeadingInfo, setShowHeadingInfo] = useState(false)
const isWhiteTheme = props.theme === TippyTheme.white
@@ -79,6 +79,8 @@ export const TippyCustomized = (props: TippyCustomizedProps) => {
additionalContent,
documentationLink,
documentationLinkText,
+ isEnterprise,
+ isExternalLink,
} = props
return (
<>
@@ -156,17 +158,16 @@ export const TippyCustomized = (props: TippyCustomizedProps) => {
)}
{additionalContent}
{documentationLink && (
-
)}
>
diff --git a/src/Common/Types.ts b/src/Common/Types.ts
index fcbb95b57..2a5597eff 100644
--- a/src/Common/Types.ts
+++ b/src/Common/Types.ts
@@ -33,6 +33,7 @@ import {
ACTION_STATE,
DEPLOYMENT_WINDOW_TYPE,
DockerConfigOverrideType,
+ DOCUMENTATION,
RefVariableType,
SortingOrder,
TaskErrorObj,
@@ -119,52 +120,60 @@ export interface CheckboxProps {
children?: ReactNode
}
-export interface TippyCustomizedProps extends Pick {
- theme: TippyTheme
- visible?: boolean
- heading?: ReactNode | string
- headingInfo?: ReactNode | string
- noHeadingBorder?: boolean
- infoTextHeading?: string
- hideHeading?: boolean
- placement?: TippyProps['placement']
- className?: string
- Icon?: React.FunctionComponent>
- iconPath?: string
- iconClass?: string
- iconSize?: number // E.g. 16, 20, etc.. Currently, there are around 12 sizes supported. Check `icons.css` or `base.scss` for supported sizes or add new size (class names starts with `icon-dim-`).
- onImageLoadError?: (e) => void
- onClose?: () => void
- infoText?: React.ReactNode
- showCloseButton?: boolean
- arrow?: boolean
- interactive?: boolean
- showOnCreate?: boolean
- trigger?: string
- animation?: string
- duration?: number
- additionalContent?: ReactNode
- documentationLink?: string
- documentationLinkText?: string
- children: React.ReactElement
- disableClose?: boolean
-}
-
-export interface InfoIconTippyProps
+export type TippyWithBaseDocLinkTypes = {
+ isExternalLink?: T
+ isEnterprise?: boolean
+ documentationLink?: T extends true ? string : keyof typeof DOCUMENTATION
+}
+
+export type TippyCustomizedProps = Pick &
+ TippyWithBaseDocLinkTypes & {
+ theme: TippyTheme
+ visible?: boolean
+ heading?: ReactNode | string
+ headingInfo?: ReactNode | string
+ noHeadingBorder?: boolean
+ infoTextHeading?: string
+ hideHeading?: boolean
+ placement?: TippyProps['placement']
+ className?: string
+ Icon?: React.FunctionComponent>
+ iconPath?: string
+ iconClass?: string
+ iconSize?: number // E.g. 16, 20, etc.. Currently, there are around 12 sizes supported. Check `icons.css` or `base.scss` for supported sizes or add new size (class names starts with `icon-dim-`).
+ onImageLoadError?: (e) => void
+ onClose?: () => void
+ infoText?: React.ReactNode
+ showCloseButton?: boolean
+ arrow?: boolean
+ interactive?: boolean
+ showOnCreate?: boolean
+ trigger?: string
+ animation?: string
+ duration?: number
+ additionalContent?: ReactNode
+ documentationLinkText?: string
+ children: React.ReactElement
+ disableClose?: boolean
+ }
+
+export interface InfoIconTippyProps
extends Pick<
- TippyCustomizedProps,
+ TippyCustomizedProps,
| 'heading'
| 'infoText'
| 'iconClass'
- | 'documentationLink'
| 'documentationLinkText'
| 'additionalContent'
| 'placement'
| 'Icon'
| 'headingInfo'
+ | 'documentationLink'
+ | 'isEnterprise'
+ | 'isExternalLink'
> {
dataTestid?: string
- children?: TippyCustomizedProps['children']
+ children?: TippyCustomizedProps['children']
iconClassName?: string
buttonPadding?: string
}
diff --git a/src/Common/index.ts b/src/Common/index.ts
index dc619f806..95b97700f 100644
--- a/src/Common/index.ts
+++ b/src/Common/index.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+export * from '../Shared/DocLink'
export * from './AddCDButton'
export * from './API'
export { BreadCrumb, useBreadcrumb } from './BreadCrumb/BreadCrumb'
diff --git a/src/Pages/Applications/DevtronApps/Details/AppConfigurations/DeploymentTemplate/DTApplicationMetricsFormField.tsx b/src/Pages/Applications/DevtronApps/Details/AppConfigurations/DeploymentTemplate/DTApplicationMetricsFormField.tsx
index 4ca82f852..5ffea8c0e 100644
--- a/src/Pages/Applications/DevtronApps/Details/AppConfigurations/DeploymentTemplate/DTApplicationMetricsFormField.tsx
+++ b/src/Pages/Applications/DevtronApps/Details/AppConfigurations/DeploymentTemplate/DTApplicationMetricsFormField.tsx
@@ -16,7 +16,6 @@
import { ReactComponent as ICInfoFilledOverride } from '@Icons/ic-info-filled-override.svg'
import { Checkbox } from '@Common/Checkbox'
-import { DOCUMENTATION } from '@Common/Constants'
import { Progressing } from '@Common/Progressing'
import { Tooltip } from '@Common/Tooltip'
import { CHECKBOX_VALUE } from '@Common/Types'
@@ -96,7 +95,7 @@ const DTApplicationMetricsFormField = ({
diff --git a/src/Shared/Components/AppStatusModal/AppStatusBody.tsx b/src/Shared/Components/AppStatusModal/AppStatusBody.tsx
index 7c8c2e2dd..b50a568b4 100644
--- a/src/Shared/Components/AppStatusModal/AppStatusBody.tsx
+++ b/src/Shared/Components/AppStatusModal/AppStatusBody.tsx
@@ -19,7 +19,7 @@ import { getAppStatusMessageFromAppDetails } from './utils'
const InfoCardItem = ({ heading, value, isLast = false, alignCenter = false }: InfoCardItemProps) => (
{heading}
diff --git a/src/Shared/Components/CICDHistory/Artifacts.tsx b/src/Shared/Components/CICDHistory/Artifacts.tsx
index 9e4f2beda..1975273eb 100644
--- a/src/Shared/Components/CICDHistory/Artifacts.tsx
+++ b/src/Shared/Components/CICDHistory/Artifacts.tsx
@@ -24,17 +24,11 @@ import folder from '@Icons/ic-folder.svg'
import { ReactComponent as ICHelpOutline } from '@Icons/ic-help.svg'
import { ReactComponent as MechanicalOperation } from '@Icons/ic-mechanical-operation.svg'
import noartifact from '@Images/no-artifact.webp'
+import { DocLink } from '@Shared/DocLink'
import { getIsApprovalPolicyConfigured } from '@Shared/Helpers'
import { useDownload } from '@Shared/Hooks'
-import {
- ClipboardButton,
- DOCUMENTATION,
- extractImage,
- GenericEmptyState,
- ImageTagsContainer,
- useGetUserRoles,
-} from '../../../Common'
+import { ClipboardButton, extractImage, GenericEmptyState, ImageTagsContainer, useGetUserRoles } from '../../../Common'
import { EMPTY_STATE_STATUS } from '../../constants'
import { TargetPlatformBadgeList } from '../TargetPlatforms'
import { TERMINAL_STATUS_MAP } from './constants'
@@ -274,14 +268,11 @@ const Artifacts = ({
{EMPTY_STATE_STATUS.ARTIFACTS_EMPTY_STATE_TEXTS.StoreFiles}
-
- {EMPTY_STATE_STATUS.ARTIFACTS_EMPTY_STATE_TEXTS.ConfigureBlobStorage}
-
+
diff --git a/src/Shared/Components/CICDHistory/LogsRenderer.tsx b/src/Shared/Components/CICDHistory/LogsRenderer.tsx
index 5f82948ff..e0f9266e2 100644
--- a/src/Shared/Components/CICDHistory/LogsRenderer.tsx
+++ b/src/Shared/Components/CICDHistory/LogsRenderer.tsx
@@ -23,6 +23,7 @@ import { ReactComponent as ICArrow } from '@Icons/ic-caret-down.svg'
import { ReactComponent as ICCollapseAll } from '@Icons/ic-collapse-all.svg'
import { ReactComponent as ICExpandAll } from '@Icons/ic-expand-all.svg'
import { ANSI_UP_REGEX, ComponentSizeType } from '@Shared/constants'
+import { DocLink } from '@Shared/DocLink'
import { escapeRegExp, sanitizeTargetPlatforms } from '@Shared/Helpers'
import { AppThemeType, getComponentSpecificThemeClass } from '@Shared/Providers'
@@ -30,7 +31,6 @@ import { ReactComponent as OpenInNew } from '../../../Assets/Icon/ic-arrow-out.s
import { ReactComponent as HelpIcon } from '../../../Assets/Icon/ic-help.svg'
import { ReactComponent as Info } from '../../../Assets/Icon/ic-info-filled.svg'
import {
- DOCUMENTATION,
Host,
Progressing,
ROUTES,
@@ -82,14 +82,8 @@ const renderBlobNotConfigured = (): JSX.Element => (
>
diff --git a/src/Shared/Components/CodeEditor/CodeEditor.tsx b/src/Shared/Components/CodeEditor/CodeEditor.tsx
index 22838f114..abd9cd3b0 100644
--- a/src/Shared/Components/CodeEditor/CodeEditor.tsx
+++ b/src/Shared/Components/CodeEditor/CodeEditor.tsx
@@ -33,7 +33,7 @@ import {
} from '@uiw/react-codemirror'
import { DEFAULT_JSON_SCHEMA_URI, MODES } from '@Common/Constants'
-import { cleanKubeManifest } from '@Common/Helper'
+import { cleanKubeManifest, noop } from '@Common/Helper'
import { getUniqueId } from '@Shared/Helpers'
import { AppThemeType, useTheme } from '@Shared/Providers'
@@ -43,8 +43,8 @@ import { getCodeEditorTheme } from './CodeEditor.theme'
import { CodeEditorRenderer } from './CodeEditorRenderer'
import {
blurOnEscape,
- openSearchPanel,
- openSearchPanelWithReplace,
+ getOpenSearchPanel,
+ getOpenSearchPanelWithReplace,
replaceAll,
showReplaceFieldState,
} from './Commands'
@@ -89,6 +89,7 @@ const CodeEditor = ({
onFocus,
autoFocus,
disableSearch = false,
+ onOpenSearchPanel = noop,
}: CodeEditorProps) => {
// HOOKS
const { appTheme } = useTheme()
@@ -203,9 +204,11 @@ const CodeEditor = ({
themeExtension,
keymap.of([
...vscodeKeymap.filter(({ key }) => key !== 'Mod-Alt-Enter' && key !== 'Mod-Enter' && key !== 'Mod-f'),
- ...(!disableSearch ? [{ key: 'Mod-f', run: openSearchPanel, scope: 'editor search-panel' }] : []),
+ ...(!disableSearch
+ ? [{ key: 'Mod-f', run: getOpenSearchPanel(onOpenSearchPanel), scope: 'editor search-panel' }]
+ : []),
{ key: 'Mod-Enter', run: replaceAll, scope: 'editor search-panel' },
- { key: 'Mod-Alt-f', run: openSearchPanelWithReplace, scope: 'editor search-panel' },
+ { key: 'Mod-Alt-f', run: getOpenSearchPanelWithReplace(onOpenSearchPanel), scope: 'editor search-panel' },
{ key: 'Escape', run: blurOnEscape, stopPropagation: true },
]),
indentationMarkers(),
diff --git a/src/Shared/Components/CodeEditor/Commands/findAndReplace.ts b/src/Shared/Components/CodeEditor/Commands/findAndReplace.ts
index d1257618b..94d0c9397 100644
--- a/src/Shared/Components/CodeEditor/Commands/findAndReplace.ts
+++ b/src/Shared/Components/CodeEditor/Commands/findAndReplace.ts
@@ -37,19 +37,22 @@ export const getShowReplaceField = (state: EditorState) => {
return curState || false
}
-export const openSearchPanel: Command = (view: EditorView) => {
- view.dispatch({
- effects: [setShowReplaceField.of(searchPanelOpen(view.state) ? getShowReplaceField(view.state) : false)],
- })
- cmOpenSearchPanel(view)
- return true
-}
+export const getOpenSearchPanel: (onOpenSearchPanel: () => void) => Command =
+ (onOpenSearchPanel: () => void) => (view: EditorView) => {
+ view.dispatch({
+ effects: [setShowReplaceField.of(searchPanelOpen(view.state) ? getShowReplaceField(view.state) : false)],
+ })
+ cmOpenSearchPanel(view)
+ onOpenSearchPanel()
+ return true
+ }
-export const openSearchPanelWithReplace: Command = (view: EditorView) => {
- openSearchPanel(view)
- view.dispatch({ effects: [setShowReplaceField.of(!view.state.readOnly && true)] })
- return true
-}
+export const getOpenSearchPanelWithReplace: (onOpenSearchPanel: () => void) => Command =
+ (onOpenSearchPanel: () => void) => (view: EditorView) => {
+ getOpenSearchPanel(onOpenSearchPanel)(view)
+ view.dispatch({ effects: [setShowReplaceField.of(!view.state.readOnly && true)] })
+ return true
+ }
export const replaceAll: Command = (view: EditorView) => {
const isReplaceEnabled = getShowReplaceField(view.state)
diff --git a/src/Shared/Components/CodeEditor/types.ts b/src/Shared/Components/CodeEditor/types.ts
index 1ffb86fd1..6eef70edc 100644
--- a/src/Shared/Components/CodeEditor/types.ts
+++ b/src/Shared/Components/CodeEditor/types.ts
@@ -78,6 +78,7 @@ export type CodeEditorProps = {
disableSearch?: boolean
diffView?: DiffView
theme?: AppThemeType
+ onOpenSearchPanel?: () => void
} & CodeEditorPropsBasedOnDiffView
export interface GetCodeEditorHeightReturnType {
diff --git a/src/Shared/Components/DeploymentStatusBreakdown/constants.ts b/src/Shared/Components/DeploymentStatusBreakdown/constants.ts
index 3b961cb7c..c9c1ceba3 100644
--- a/src/Shared/Components/DeploymentStatusBreakdown/constants.ts
+++ b/src/Shared/Components/DeploymentStatusBreakdown/constants.ts
@@ -41,6 +41,10 @@ export const WFR_STATUS_DTO_TO_DEPLOYMENT_STATUS_MAP: Readonly<
[WorkflowRunnerStatusDTO.PROGRESSING]: DEPLOYMENT_STATUS.INPROGRESS,
[WorkflowRunnerStatusDTO.QUEUED]: DEPLOYMENT_STATUS.QUEUED,
+
+ [WorkflowRunnerStatusDTO.UNKNOWN]: DEPLOYMENT_STATUS.UNKNOWN,
+ [WorkflowRunnerStatusDTO.SUSPENDED]: DEPLOYMENT_STATUS.UNKNOWN,
+ [WorkflowRunnerStatusDTO.MISSING]: DEPLOYMENT_STATUS.UNKNOWN,
}
export const PROGRESSING_DEPLOYMENT_STATUS: Readonly<(typeof DEPLOYMENT_STATUS)[keyof typeof DEPLOYMENT_STATUS][]> = [
diff --git a/src/Shared/Components/DeploymentStatusBreakdown/types.ts b/src/Shared/Components/DeploymentStatusBreakdown/types.ts
index 6c0cc185e..3ff56bf80 100644
--- a/src/Shared/Components/DeploymentStatusBreakdown/types.ts
+++ b/src/Shared/Components/DeploymentStatusBreakdown/types.ts
@@ -15,9 +15,12 @@ export enum WorkflowRunnerStatusDTO {
STARTING = 'Starting',
QUEUED = 'Queued',
INITIATING = 'Initiating',
- // Not found on BE but added for Backward compatibility
+ // Coming in specific cases of helm apps
HEALTHY = 'Healthy',
DEGRADED = 'Degraded',
+ MISSING = 'Missing',
+ UNKNOWN = 'Unknown',
+ SUSPENDED = 'Suspended',
}
export interface ProcessUnableToFetchOrTimedOutStatusType {
diff --git a/src/Shared/Components/Error/ErrorBar.tsx b/src/Shared/Components/Error/ErrorBar.tsx
index 1cf0b7bc1..ee5c2781f 100644
--- a/src/Shared/Components/Error/ErrorBar.tsx
+++ b/src/Shared/Components/Error/ErrorBar.tsx
@@ -17,7 +17,7 @@
import { NavLink } from 'react-router-dom'
import { ReactComponent as ErrorInfo } from '../../../Assets/Icon/ic-errorInfo.svg'
-import { URLS } from '../../../Common'
+import { DISCORD_LINK, URLS } from '../../../Common'
import { AppType } from '../../types'
import { ErrorBarType } from './types'
import { getIsImagePullBackOff, renderErrorHeaderMessage } from './utils'
@@ -90,7 +90,7 @@ const ErrorBar = ({ appDetails, useParentMargin = true }: ErrorBarType) => {
diff --git a/src/Shared/Components/FeatureDescription/FeatureTitleWithInfo.tsx b/src/Shared/Components/FeatureDescription/FeatureTitleWithInfo.tsx
index 88fa2f878..f36c2d2b4 100644
--- a/src/Shared/Components/FeatureDescription/FeatureTitleWithInfo.tsx
+++ b/src/Shared/Components/FeatureDescription/FeatureTitleWithInfo.tsx
@@ -38,6 +38,7 @@ const FeatureTitleWithInfo = ({
additionalContent,
showInfoIcon = false,
tabsConfig,
+ isEnterprise,
}: DescriptorProps) => {
const [showFeatureDescriptionModal, setShowFeatureDescriptionModal] = useState(false)
const onClickInfoIcon = () => {
@@ -63,6 +64,7 @@ const FeatureTitleWithInfo = ({
documentationLink={docLink}
documentationLinkText={docLinkText}
dataTestid="info-tippy-button"
+ isEnterprise={isEnterprise}
/>
)
@@ -95,6 +97,7 @@ const FeatureTitleWithInfo = ({
{
renderDescriptionContent?: () => ReactNode
- docLink?: string
+ docLink?: DocLinkProps['docLinkKey']
imageVariant?: ImageType
SVGImage?: React.FunctionComponent>
imageStyles?: React.CSSProperties
@@ -53,6 +55,7 @@ export type FeatureDescriptionModalProps = {
title: string
closeModalText?: string
closeModal?: () => void
+ isEnterprise?: boolean
} & (
| (BaseFeatureDescriptionModalProps & {
tabsConfig?: never
@@ -81,4 +84,5 @@ export type DescriptorProps = (
* @default false
*/
showInfoIcon?: boolean
+ isEnterprise?: boolean
}
diff --git a/src/Shared/Components/GenericInfoCard/GenericInfoCardListing.tsx b/src/Shared/Components/GenericInfoCard/GenericInfoCardListing.tsx
new file mode 100644
index 000000000..c8dd2704e
--- /dev/null
+++ b/src/Shared/Components/GenericInfoCard/GenericInfoCardListing.tsx
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2024. Devtron Inc.
+ */
+
+import { useMemo } from 'react'
+
+import emptyList from '@Images/empty-create.png'
+import ErrorScreenManager from '@Common/ErrorScreenManager'
+import { GenericEmptyState, GenericFilterEmptyState } from '@Common/index'
+
+import GenericInfoCard from './GenericInfoCard.component'
+import { GenericInfoListSkeleton } from './GenericInfoListSkeleton'
+import { GenericInfoCardListingProps } from './types'
+
+export const GenericInfoCardListing = ({
+ isLoading,
+ error,
+ list,
+ searchKey,
+ reloadList,
+ borderVariant,
+ handleClearFilters,
+ emptyStateConfig,
+}: GenericInfoCardListingProps) => {
+ const filteredList = useMemo(() => {
+ const sanitizedList = list || []
+ if (!searchKey || error) {
+ return sanitizedList
+ }
+
+ const loweredSearchKey = searchKey.toLowerCase()
+ return sanitizedList.filter(({ title }) => title.toLowerCase().includes(loweredSearchKey))
+ }, [searchKey, list, error])
+
+ if (isLoading) {
+ return
+ }
+
+ if (error) {
+ return
+ }
+
+ if (filteredList.length === 0) {
+ if (searchKey) {
+ return
+ }
+
+ return (
+
+ )
+ }
+
+ return (
+ <>
+ {filteredList.map(({ id, title, description, author, Icon, onClick, linkProps }) => (
+
+ ))}
+ >
+ )
+}
diff --git a/src/Shared/Components/GenericInfoCard/GenericInfoListSkeleton.tsx b/src/Shared/Components/GenericInfoCard/GenericInfoListSkeleton.tsx
new file mode 100644
index 000000000..f78f83668
--- /dev/null
+++ b/src/Shared/Components/GenericInfoCard/GenericInfoListSkeleton.tsx
@@ -0,0 +1,10 @@
+import GenericInfoCard from './GenericInfoCard.component'
+import { GenericInfoListSkeletonProps } from './types'
+
+export const GenericInfoListSkeleton = ({ borderVariant }: GenericInfoListSkeletonProps) => (
+ <>
+
+
+
+ >
+)
diff --git a/src/Shared/Components/GenericInfoCard/index.ts b/src/Shared/Components/GenericInfoCard/index.ts
index 763c46d7d..bca53f3fd 100644
--- a/src/Shared/Components/GenericInfoCard/index.ts
+++ b/src/Shared/Components/GenericInfoCard/index.ts
@@ -15,4 +15,6 @@
*/
export { default as GenericInfoCard } from './GenericInfoCard.component'
-export { GenericInfoCardBorderVariant, type GenericInfoCardProps } from './types'
+export * from './GenericInfoCardListing'
+export { GenericInfoListSkeleton } from './GenericInfoListSkeleton'
+export { GenericInfoCardBorderVariant, type GenericInfoCardListingProps, type GenericInfoCardProps } from './types'
diff --git a/src/Shared/Components/GenericInfoCard/types.ts b/src/Shared/Components/GenericInfoCard/types.ts
index 3050292f6..6c90f881f 100644
--- a/src/Shared/Components/GenericInfoCard/types.ts
+++ b/src/Shared/Components/GenericInfoCard/types.ts
@@ -17,6 +17,11 @@
import { MouseEventHandler, ReactElement } from 'react'
import { LinkProps } from 'react-router-dom'
+import { GenericFilterEmptyStateProps } from '@Common/EmptyState/types'
+import { GenericEmptyStateType } from '@Common/Types'
+
+import { APIResponseHandlerProps } from '../APIResponseHandler'
+
type BaseGenericInfoCardProps = {
title: string
description: string
@@ -46,3 +51,17 @@ export type GenericInfoCardProps = { borderVariant: GenericInfoCardBorderVariant
isLoading?: boolean
} & BaseGenericInfoCardProps)
)
+
+export interface GenericInfoCardListingProps
+ extends Pick,
+ Pick {
+ list: (Pick &
+ Record<'id', string>)[]
+ emptyStateConfig: Pick
+ searchKey?: string
+ reloadList: () => void
+ error?: APIResponseHandlerProps['error']
+ isLoading?: boolean
+}
+
+export interface GenericInfoListSkeletonProps extends Partial> {}
diff --git a/src/Shared/Components/Header/PageHeader.tsx b/src/Shared/Components/Header/PageHeader.tsx
index e30dfdedb..52fd08531 100644
--- a/src/Shared/Components/Header/PageHeader.tsx
+++ b/src/Shared/Components/Header/PageHeader.tsx
@@ -48,6 +48,7 @@ const PageHeader = ({
onClose,
markAsBeta,
tippyProps,
+ isEnterprise,
}: PageHeaderType) => {
const { loginCount, setLoginCount, showGettingStartedCard, setShowGettingStartedCard, licenseData } =
useMainContext()
@@ -154,6 +155,8 @@ const PageHeader = ({
interactive
arrow
onClose={handleCloseSwitchThemeLocationTippyChange}
+ isEnterprise={isEnterprise}
+ documentationLink={tippyRedirectLink}
>