diff --git a/package-lock.json b/package-lock.json
index 4ba478ef3..7fe5ba821 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@devtron-labs/devtron-fe-common-lib",
- "version": "1.13.0-pre-6",
+ "version": "1.13.0-pre-7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@devtron-labs/devtron-fe-common-lib",
- "version": "1.13.0-pre-6",
+ "version": "1.13.0-pre-7",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
diff --git a/package.json b/package.json
index 4227d5d2a..ae52f7481 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@devtron-labs/devtron-fe-common-lib",
- "version": "1.13.0-pre-6",
+ "version": "1.13.0-pre-7",
"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/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/Icon/Icon.tsx b/src/Shared/Components/Icon/Icon.tsx
index c3953b9fa..d6029eb8c 100644
--- a/src/Shared/Components/Icon/Icon.tsx
+++ b/src/Shared/Components/Icon/Icon.tsx
@@ -6,6 +6,7 @@ import { ReactComponent as ICAdd } from '@IconsV2/ic-add.svg'
import { ReactComponent as ICAmazonEks } from '@IconsV2/ic-amazon-eks.svg'
import { ReactComponent as ICApica } from '@IconsV2/ic-apica.svg'
import { ReactComponent as ICAppGroup } from '@IconsV2/ic-app-group.svg'
+import { ReactComponent as ICAppTemplate } from '@IconsV2/ic-app-template.svg'
import { ReactComponent as ICArrowClockwise } from '@IconsV2/ic-arrow-clockwise.svg'
import { ReactComponent as ICArrowRight } from '@IconsV2/ic-arrow-right.svg'
import { ReactComponent as ICArrowSquareOut } from '@IconsV2/ic-arrow-square-out.svg'
@@ -50,7 +51,9 @@ import { ReactComponent as ICDeleteDots } from '@IconsV2/ic-delete-dots.svg'
import { ReactComponent as ICDeleteLightning } from '@IconsV2/ic-delete-lightning.svg'
import { ReactComponent as ICDelhivery } from '@IconsV2/ic-delhivery.svg'
import { ReactComponent as ICDevtron } from '@IconsV2/ic-devtron.svg'
+import { ReactComponent as ICDevtronApp } from '@IconsV2/ic-devtron-app.svg'
import { ReactComponent as ICDevtronHeaderLogo } from '@IconsV2/ic-devtron-header-logo.svg'
+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'
@@ -163,6 +166,7 @@ export const iconMap = {
'ic-amazon-eks': ICAmazonEks,
'ic-apica': ICApica,
'ic-app-group': ICAppGroup,
+ 'ic-app-template': ICAppTemplate,
'ic-arrow-clockwise': ICArrowClockwise,
'ic-arrow-right': ICArrowRight,
'ic-arrow-square-out': ICArrowSquareOut,
@@ -206,7 +210,9 @@ export const iconMap = {
'ic-delete-lightning': ICDeleteLightning,
'ic-delete': ICDelete,
'ic-delhivery': ICDelhivery,
+ 'ic-devtron-app': ICDevtronApp,
'ic-devtron-header-logo': ICDevtronHeaderLogo,
+ 'ic-devtron-job': ICDevtronJob,
'ic-devtron': ICDevtron,
'ic-disconnect': ICDisconnect,
'ic-discord-fill': ICDiscordFill,