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,