From 9d9439ca091c542c7d973b48a4edce6dcddaaf2b Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Fri, 8 Nov 2024 18:11:03 +0530 Subject: [PATCH 01/12] feat: add new props and export design table Signed-off-by: Amit Amrutiya --- src/custom/CustomCatalog/CustomCard.tsx | 3 +++ .../CustomColumnVisibilityControl.tsx | 4 +++- src/custom/index.tsx | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/custom/CustomCatalog/CustomCard.tsx b/src/custom/CustomCatalog/CustomCard.tsx index 0a105755..13233bb6 100644 --- a/src/custom/CustomCatalog/CustomCard.tsx +++ b/src/custom/CustomCatalog/CustomCard.tsx @@ -45,6 +45,9 @@ export interface Pattern { first_name: string; last_name: string; }; + first_name?: string; + last_name?: string; + avatar_url: string; name: string; download_count: number; clone_count: number; diff --git a/src/custom/CustomColumnVisibilityControl/CustomColumnVisibilityControl.tsx b/src/custom/CustomColumnVisibilityControl/CustomColumnVisibilityControl.tsx index 36bfc06b..7541891d 100644 --- a/src/custom/CustomColumnVisibilityControl/CustomColumnVisibilityControl.tsx +++ b/src/custom/CustomColumnVisibilityControl/CustomColumnVisibilityControl.tsx @@ -27,7 +27,8 @@ export interface CustomColumn { export function CustomColumnVisibilityControl({ columns, id, - customToolsProps + customToolsProps, + style }: CustomColumnVisibilityControlProps): JSX.Element { const [open, setOpen] = React.useState(false); const [anchorEl, setAnchorEl] = React.useState(null); @@ -60,6 +61,7 @@ export function CustomColumnVisibilityControl({ arrow /> Date: Fri, 8 Nov 2024 18:11:27 +0530 Subject: [PATCH 02/12] feat: create catalog design table component Signed-off-by: Amit Amrutiya --- .../CatalogDesignTable/CatalogDesignTable.tsx | 110 ++++++++++++++++++ src/custom/CatalogDesignTable/index.ts | 3 + 2 files changed, 113 insertions(+) create mode 100644 src/custom/CatalogDesignTable/CatalogDesignTable.tsx create mode 100644 src/custom/CatalogDesignTable/index.ts diff --git a/src/custom/CatalogDesignTable/CatalogDesignTable.tsx b/src/custom/CatalogDesignTable/CatalogDesignTable.tsx new file mode 100644 index 00000000..c02c8f69 --- /dev/null +++ b/src/custom/CatalogDesignTable/CatalogDesignTable.tsx @@ -0,0 +1,110 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import _ from 'lodash'; +import { useEffect, useState } from 'react'; +import { Pattern } from '../CustomCatalog/CustomCard'; +import { useWindowDimensions } from '../Helpers/Dimension'; +import ResponsiveDataTable from '../ResponsiveDataTable'; + +interface CatalogDesignsTableProps { + patters: Pattern[]; + filter: any; + columns: Array; + totalCount: number; + sortOrder: string; + setSortOrder: (order: string) => void; + pageSize: number; + setPageSize: (size: number) => void; + page: number; + setPage: (page: number) => void; + columnVisibility: Record; + colViews: any; +} + +export const CatalogDesignsTable: React.FC = ({ + patters, + filter, + columns = [], + totalCount = 0, + sortOrder = '', + setSortOrder, + pageSize = 10, + setPageSize, + page = 0, + setPage, + columnVisibility = {}, + colViews = {} +}) => { + const [tableCols, updateCols] = useState>([]); + const { width } = useWindowDimensions(); + const smallScreen = width <= 360; + // const modalRef = useRef(null); + + useEffect(() => { + if (Array.isArray(columns) && columns.length > 0) { + updateCols(columns); + } + }, [columns]); + + const options = { + selectableRows: _.isNil(filter) ? 'none' : 'multiple', + serverSide: true, + filterType: 'multiselect', + responsive: smallScreen ? 'vertical' : 'standard', + count: totalCount, + rowsPerPage: pageSize, + page, + elevation: 0, + search: false, + filter: false, + download: false, + print: false, + viewColumns: false, + onTableChange: (action: string, tableState: any) => { + const sortInfo = tableState.announceText ? tableState.announceText.split(' : ') : []; + let order = ''; + + switch (action) { + case 'changePage': + setPage(tableState.page); + break; + case 'changeRowsPerPage': + setPageSize(tableState.rowsPerPage); + break; + case 'sort': + if ( + sortInfo.length === 2 && + tableState.activeColumn !== undefined && + Array.isArray(columns) + ) { + if (sortInfo[1] === 'ascending') { + order = `${columns[tableState.activeColumn].name} asc`; + } else { + order = `${columns[tableState.activeColumn].name} desc`; + } + } + if (order !== sortOrder) { + setSortOrder(order); + } + break; + } + } + }; + + if (!Array.isArray(tableCols) || tableCols.length === 0) { + return null; + } + + return ( + Object.values(pattern)) ?? []} + options={options} + colViews={colViews} + tableCols={tableCols} + updateCols={updateCols} + columnVisibility={columnVisibility} + /> + ); +}; + +export default CatalogDesignsTable; diff --git a/src/custom/CatalogDesignTable/index.ts b/src/custom/CatalogDesignTable/index.ts new file mode 100644 index 00000000..54b68af3 --- /dev/null +++ b/src/custom/CatalogDesignTable/index.ts @@ -0,0 +1,3 @@ +import CatalogDesignsTable from './CatalogDesignTable'; +import ColumnConfig from './columnConfig'; +export { CatalogDesignsTable, ColumnConfig }; From 570794ab79eefc7f036ec8ffffe80924a7e47ec4 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Fri, 8 Nov 2024 18:11:41 +0530 Subject: [PATCH 03/12] feat: create catalog design config data file Signed-off-by: Amit Amrutiya --- .../CatalogDesignTable/columnConfig.tsx | 339 ++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 src/custom/CatalogDesignTable/columnConfig.tsx diff --git a/src/custom/CatalogDesignTable/columnConfig.tsx b/src/custom/CatalogDesignTable/columnConfig.tsx new file mode 100644 index 00000000..8d0f20dc --- /dev/null +++ b/src/custom/CatalogDesignTable/columnConfig.tsx @@ -0,0 +1,339 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { useTheme } from '@mui/material'; +import { MUIDataTableColumn, MUIDataTableMeta } from 'mui-datatables'; +import { FacebookShareButton, LinkedinShareButton, TwitterShareButton } from 'react-share'; +import { Avatar, Box, Grid, Typography } from '../../base'; +import { iconMedium } from '../../constants/iconsSizes'; +import { + ChainIcon, + CopyIcon, + DownloadIcon, + FacebookIcon, + LinkedinIcon, + PersonIcon, + PublishIcon, + TwitterIcon +} from '../../icons'; +import { Pattern } from '../CustomCatalog/CustomCard'; +import { CustomTooltip } from '../CustomTooltip'; +import { ConditionalTooltip } from '../Helpers/CondtionalTooltip'; +import { DataTableEllipsisMenu } from '../ResponsiveDataTable'; + +export const colViews = [ + ['id', 'na'], + ['name', 'xs'], + ['first_name', 'xs'], + ['last_name', 'na'], + ['created_at', 'na'], + ['updated_at', 'l'], + ['design_type', 'xs'], + ['class', 'l'], + ['view_count', 'na'], + ['download_count', 'na'], + ['clone_count', 'na'], + ['deployment_count', 'na'], + ['share_count', 'na'], + ['actions', 'xs'] +]; + +interface ColumnConfigProps { + handleShowDetails: (design: Pattern) => void; + handleCardClick: (design: Pattern) => void; + handleCopyUrl: (design: Pattern) => void; + maxWidth?: boolean; + getCatalogUrl: (type: string, name: string) => string; +} + +interface ActionItem { + title: string; + icon?: JSX.Element; + onClick?: () => void; + disabled?: boolean; + customComponent?: JSX.Element; + type?: string; +} + +export const createColumns = ( + { + handleShowDetails, + handleCardClick, + handleCopyUrl, + maxWidth = true, + getCatalogUrl + }: ColumnConfigProps, + theme: any +): MUIDataTableColumn[] => { + const getColumnValue = (tableMeta: MUIDataTableMeta, targetColumn: string): any => { + const rowData = tableMeta.tableData[tableMeta.rowIndex] as Pattern; + return (rowData as any)[targetColumn] || ''; + }; + + return [ + { + name: 'id', + label: 'ID', + options: { + filter: false, + customBodyRender: (value: string) => + } + }, + { + name: 'name', + label: 'Name', + options: { + filter: false, + sort: true, + searchable: true, + customBodyRender: (value: string, tableMeta: MUIDataTableMeta) => { + const design = tableMeta.tableData[tableMeta.rowIndex] as Pattern; + return ( +
handleShowDetails(design)} style={{ cursor: 'pointer' }}> + {value} +
+ ); + } + } + }, + { + name: 'avatar_url', + label: 'Avatar', + options: { + display: false + } + }, + { + name: 'user_id', + label: 'User ID', + options: { + display: false + } + }, + { + name: 'first_name', + label: 'Author', + options: { + filter: false, + sort: true, + searchable: true, + customBodyRender: (_: string, tableMeta: MUIDataTableMeta) => { + const firstName = getColumnValue(tableMeta, 'first_name'); + const lastName = getColumnValue(tableMeta, 'last_name'); + const avatar_url = getColumnValue(tableMeta, 'avatar_url'); + const user_id = getColumnValue(tableMeta, 'user_id'); + const displayName = + firstName && lastName + ? `${firstName} ${lastName}` + : firstName + ? firstName + : lastName + ? lastName + : ''; + + return ( + img': { mr: 2, flexShrink: 0 } }}> + + + + +
+ { + window.location.href = `/user/${user_id}`; + }} + > + {!avatar_url && } + +
+
+
+
+ {maxWidth && ( + + {displayName} + + )} +
+
+ ); + } + } + }, + { + name: 'last_name', + label: 'Last Name', + options: { + display: false + } + }, + { + name: 'created_at', + label: 'Created At', + options: { + filter: false, + sort: true, + searchable: true + } + }, + { + name: 'updated_at', + label: 'Updated At', + options: { + filter: false, + sort: true, + searchable: true + } + }, + { + name: 'design_type', + label: 'Type', + options: { + filter: true, + sort: false, + searchable: true + } + }, + { + name: 'class', + label: 'Class', + options: { + filter: true, + sort: false, + searchable: true + } + }, + { + name: 'view_count', + label: 'Opens', + options: { + filter: false, + sort: true + } + }, + { + name: 'download_count', + label: 'Downloads', + options: { + filter: false, + sort: true + } + }, + { + name: 'clone_count', + label: 'Clones', + options: { + filter: false, + sort: true + } + }, + { + name: 'deployment_count', + label: 'Deploys', + options: { + filter: false, + sort: true + } + }, + { + name: 'share_count', + label: 'Shares', + options: { + filter: false, + sort: true + } + }, + { + name: 'actions', + label: 'Actions', + options: { + filter: false, + sort: false, + searchable: false, + setCellHeaderProps: () => ({ align: 'center' as const }), + setCellProps: () => ({ align: 'center' as const }), + customBodyRender: (_: any, tableMeta: MUIDataTableMeta) => { + const rowData = tableMeta.tableData[tableMeta.rowIndex] as Pattern; + + const constructMessage = () => { + return `Check out ${rowData.first_name} ${rowData.last_name}'s design "${rowData.name}" on Layer5's Catalog`; + }; + + const actionsList: ActionItem[] = [ + { + title: 'Clone', + onClick: () => handleCardClick(rowData), + disabled: false, + icon: + }, + { + title: 'Download', + onClick: () => {}, + icon: + }, + { + title: 'Unpublish', + onClick: () => {}, + disabled: false, + icon: + }, + { + title: 'Copy Link', + onClick: () => handleCopyUrl(rowData), + icon: + }, + { + title: 'Share Design via Socials', + type: 'share-social', + customComponent: ( +
+ + + + + + + + + +
+ ) + } + ]; + //@ts-ignore + return ; + } + } + } + ]; +}; + +//@ts-ignore +const ColumnConfig: React.FC = (props) => { + const theme = useTheme(); + return createColumns(props, theme); +}; + +export default ColumnConfig; From e3d40cc3e130807bf582084909738c9d8adb4c3b Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 11 Nov 2024 12:38:21 +0530 Subject: [PATCH 04/12] feat: add functionlity of the action items Signed-off-by: Amit Amrutiya --- .../CatalogDesignTable/columnConfig.tsx | 119 +++++++++++------- 1 file changed, 77 insertions(+), 42 deletions(-) diff --git a/src/custom/CatalogDesignTable/columnConfig.tsx b/src/custom/CatalogDesignTable/columnConfig.tsx index 8d0f20dc..ce5feceb 100644 --- a/src/custom/CatalogDesignTable/columnConfig.tsx +++ b/src/custom/CatalogDesignTable/columnConfig.tsx @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { useTheme } from '@mui/material'; import { MUIDataTableColumn, MUIDataTableMeta } from 'mui-datatables'; import { FacebookShareButton, LinkedinShareButton, TwitterShareButton } from 'react-share'; import { Avatar, Box, Grid, Typography } from '../../base'; @@ -10,17 +9,23 @@ import { CopyIcon, DownloadIcon, FacebookIcon, + KanvasIcon, LinkedinIcon, PersonIcon, PublishIcon, TwitterIcon } from '../../icons'; +import { downloadFilter, downloadYaml } from '../CatalogDetail/helper'; +import { RESOURCE_TYPES } from '../CatalogDetail/types'; import { Pattern } from '../CustomCatalog/CustomCard'; import { CustomTooltip } from '../CustomTooltip'; import { ConditionalTooltip } from '../Helpers/CondtionalTooltip'; import { DataTableEllipsisMenu } from '../ResponsiveDataTable'; +import { NameDiv } from './style'; -export const colViews = [ +export type ColView = [string, 'na' | 'xs' | 'l']; + +export const colViews: ColView[] = [ ['id', 'na'], ['name', 'xs'], ['first_name', 'xs'], @@ -39,10 +44,18 @@ export const colViews = [ interface ColumnConfigProps { handleShowDetails: (design: Pattern) => void; - handleCardClick: (design: Pattern) => void; + handleCloneClick: (design: Pattern) => void; handleCopyUrl: (design: Pattern) => void; + handleOpenPlayground: (design: Pattern) => void; + handleUnpublish?: (design: Pattern) => void; maxWidth?: boolean; getCatalogUrl: (type: string, name: string) => string; + type?: string; + theme?: any; + showUnpublish?: boolean; + currentUserId?: string; + isCloneDisabled?: boolean; + isUnpublishDisabled?: boolean; } interface ActionItem { @@ -54,17 +67,25 @@ interface ActionItem { type?: string; } -export const createColumns = ( - { - handleShowDetails, - handleCardClick, - handleCopyUrl, - maxWidth = true, - getCatalogUrl - }: ColumnConfigProps, - theme: any -): MUIDataTableColumn[] => { +export const createDesignColumns = ({ + handleShowDetails, + handleCloneClick, + handleCopyUrl, + handleOpenPlayground, + handleUnpublish = () => {}, + maxWidth = true, + getCatalogUrl, + type, + theme, + showUnpublish, + currentUserId, + isCloneDisabled, + isUnpublishDisabled +}: ColumnConfigProps): MUIDataTableColumn[] => { + const cleanedType = type?.replace('my-', '').replace(/s$/, ''); const getColumnValue = (tableMeta: MUIDataTableMeta, targetColumn: string): any => { + console.log('amitas targetColumn', tableMeta); + //@ts-ignore const rowData = tableMeta.tableData[tableMeta.rowIndex] as Pattern; return (rowData as any)[targetColumn] || ''; }; @@ -86,12 +107,9 @@ export const createColumns = ( sort: true, searchable: true, customBodyRender: (value: string, tableMeta: MUIDataTableMeta) => { + //@ts-ignore const design = tableMeta.tableData[tableMeta.rowIndex] as Pattern; - return ( -
handleShowDetails(design)} style={{ cursor: 'pointer' }}> - {value} -
- ); + return handleShowDetails(design)}>{value}; } } }, @@ -256,33 +274,39 @@ export const createColumns = ( filter: false, sort: false, searchable: false, - setCellHeaderProps: () => ({ align: 'center' as const }), - setCellProps: () => ({ align: 'center' as const }), + setCellHeaderProps: () => ({ align: 'center' }), + setCellProps: () => ({ align: 'center' }), customBodyRender: (_: any, tableMeta: MUIDataTableMeta) => { + //@ts-ignore const rowData = tableMeta.tableData[tableMeta.rowIndex] as Pattern; - const constructMessage = () => { - return `Check out ${rowData.first_name} ${rowData.last_name}'s design "${rowData.name}" on Layer5's Catalog`; - }; + function constructMessage() { + const currentUser = rowData?.user_id === currentUserId; + if (currentUser) { + return `Check out my design "${rowData?.name}" on Layer5's Catalog`; + } else { + return `Check out ${ + rowData?.first_name + ' ' + rowData.last_name + }'s design "${rowData?.name}" on Layer5's Catalog`; + } + } - const actionsList: ActionItem[] = [ + const baseActions: ActionItem[] = [ { title: 'Clone', - onClick: () => handleCardClick(rowData), - disabled: false, - icon: + onClick: () => handleCloneClick(rowData), + disabled: isCloneDisabled, + icon: }, { title: 'Download', - onClick: () => {}, + onClick: () => { + cleanedType === RESOURCE_TYPES.FILTERS + ? downloadFilter(rowData.id, rowData.name) + : downloadYaml(rowData.pattern_file, rowData.name); + }, icon: }, - { - title: 'Unpublish', - onClick: () => {}, - disabled: false, - icon: - }, { title: 'Copy Link', onClick: () => handleCopyUrl(rowData), @@ -320,8 +344,27 @@ export const createColumns = ( ) + }, + { + title: 'Open in playground', + onClick: () => handleOpenPlayground(rowData), + icon: } ]; + // TODO: make this unbpublish action work for playgroud + const actionsList = showUnpublish + ? [ + ...baseActions.slice(0, 2), + { + title: 'Unpublish', + onClick: () => handleUnpublish(rowData), + disabled: isUnpublishDisabled, + icon: + }, + ...baseActions.slice(2) + ] + : baseActions; + //@ts-ignore return ; } @@ -329,11 +372,3 @@ export const createColumns = ( } ]; }; - -//@ts-ignore -const ColumnConfig: React.FC = (props) => { - const theme = useTheme(); - return createColumns(props, theme); -}; - -export default ColumnConfig; From f3ac99a253564c2dd7ca4a2e7ff1588ef1d2a9f9 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 11 Nov 2024 12:39:06 +0530 Subject: [PATCH 05/12] feat: enhance CatalogDesignTable exports and add styled component Signed-off-by: Amit Amrutiya --- src/custom/CatalogDesignTable/index.ts | 4 ++-- src/custom/CatalogDesignTable/style.tsx | 11 +++++++++++ src/custom/Prompt/promt-component.tsx | 2 +- src/custom/index.tsx | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 src/custom/CatalogDesignTable/style.tsx diff --git a/src/custom/CatalogDesignTable/index.ts b/src/custom/CatalogDesignTable/index.ts index 54b68af3..50831504 100644 --- a/src/custom/CatalogDesignTable/index.ts +++ b/src/custom/CatalogDesignTable/index.ts @@ -1,3 +1,3 @@ import CatalogDesignsTable from './CatalogDesignTable'; -import ColumnConfig from './columnConfig'; -export { CatalogDesignsTable, ColumnConfig }; +import { colViews, createDesignColumns } from './columnConfig'; +export { CatalogDesignsTable, colViews, createDesignColumns }; diff --git a/src/custom/CatalogDesignTable/style.tsx b/src/custom/CatalogDesignTable/style.tsx new file mode 100644 index 00000000..502129fe --- /dev/null +++ b/src/custom/CatalogDesignTable/style.tsx @@ -0,0 +1,11 @@ +import { styled } from '@mui/material'; + +export const NameDiv = styled('div')({ + cursor: 'pointer', + fontWeight: 'bold', + textDecoration: 'none', + + '&:hover': { + textDecoration: 'underline' + } +}); diff --git a/src/custom/Prompt/promt-component.tsx b/src/custom/Prompt/promt-component.tsx index 9d1cba78..44022d73 100644 --- a/src/custom/Prompt/promt-component.tsx +++ b/src/custom/Prompt/promt-component.tsx @@ -35,7 +35,7 @@ interface ShowParams { showInfoIcon?: string; } -interface PromptRef { +export interface PromptRef { show: (params: ShowParams) => Promise; } diff --git a/src/custom/index.tsx b/src/custom/index.tsx index b89196ab..ed6517cc 100644 --- a/src/custom/index.tsx +++ b/src/custom/index.tsx @@ -44,7 +44,7 @@ import { TransferList } from './TransferModal/TransferList'; import { TransferListProps } from './TransferModal/TransferList/TransferList'; import UniversalFilter, { UniversalFilterProps } from './UniversalFilter'; export { CatalogCard } from './CatalogCard'; -export { CatalogDesignsTable, ColumnConfig } from './CatalogDesignTable'; +export { CatalogDesignsTable, colViews, createDesignColumns } from './CatalogDesignTable'; export { CatalogFilterSidebar } from './CatalogFilterSection'; export type { FilterListType } from './CatalogFilterSection'; export { StyledChartDialog } from './ChartDialog'; From 31f0dd79184bc014622683c7a13529333a763fc5 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 11 Nov 2024 12:39:38 +0530 Subject: [PATCH 06/12] fix: theme issue passing on responsive table Signed-off-by: Amit Amrutiya --- src/custom/ResponsiveDataTable.tsx | 124 +++++++++++++++++++---------- 1 file changed, 80 insertions(+), 44 deletions(-) diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index 9216e5bd..c1e79b53 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -4,6 +4,7 @@ import React, { useCallback } from 'react'; import { Checkbox, Collapse, ListItemIcon, ListItemText, Menu, MenuItem } from '../base'; import { ShareIcon } from '../icons'; import { EllipsisIcon } from '../icons/Ellipsis'; +import { useTheme } from '../theme'; import TooltipIcon from './TooltipIcon'; export const IconWrapper = styled('div')<{ disabled?: boolean }>(({ disabled = false }) => ({ @@ -40,16 +41,56 @@ export const DataTableEllipsisMenu: React.FC<{ handleClose(); } }; - + const theme = useTheme(); return ( <> - } arrow /> - + } + arrow + /> + {actionsList && - actionsList.map((action, index) => ( - - {action.type === 'share-social' ? ( - <> + actionsList.map((action, index) => { + if (action.type === 'share-social') { + return [ + handleActionClick(action)} + disabled={action.disabled} + > + + + + {action.title} + , + + {action.customComponent} + + ]; + } else { + return ( + handleActionClick(action)} disabled={action.disabled} > - - - + {action.icon} {action.title} - - {action.customComponent} - - - ) : ( - <> - - handleActionClick(action)} - disabled={action.disabled} - > - {action.icon} - {action.title} - - - - )} - - ))} + + ); + } + })} ); }; -const dataTableTheme = (theme: Theme) => +const dataTableTheme = (theme: Theme, backgroundColor?: string) => createTheme({ components: { + MUIDataTable: { + styleOverrides: { + paper: { + background: backgroundColor || theme.palette.background.default, + maxWidth: '-moz-available' + } + } + }, MuiTable: { styleOverrides: { root: { @@ -103,7 +130,7 @@ const dataTableTheme = (theme: Theme) => '@media (max-width: 500px)': { wordWrap: 'break-word' }, - background: theme.palette.background.constant?.table, + background: backgroundColor || theme.palette.background.constant?.table, color: theme.palette.text.default } } @@ -118,7 +145,8 @@ const dataTableTheme = (theme: Theme) => root: { fontWeight: 'bold', textTransform: 'uppercase', - color: theme.palette.text.default + color: theme.palette.text.default, + backgroundColor: backgroundColor || theme.palette.background.constant?.table } } }, @@ -187,7 +215,7 @@ const dataTableTheme = (theme: Theme) => MUIDataTableSelectCell: { styleOverrides: { headerCell: { - background: theme.palette.background.constant?.table + background: backgroundColor || theme.palette.background.constant?.table } } }, @@ -249,8 +277,8 @@ export interface ResponsiveDataTableProps { theme?: object; colViews?: Record | undefined; rowsPerPageOptions?: number[] | undefined; + backgroundColor?: string; } - const ResponsiveDataTable = ({ data, columns, @@ -258,7 +286,9 @@ const ResponsiveDataTable = ({ tableCols, updateCols, columnVisibility, - rowsPerPageOptions = [10, 25, 50, 100], // Default and standard page size options + rowsPerPageOptions = [10, 25, 50, 100], + theme, + backgroundColor, ...props }: ResponsiveDataTableProps): JSX.Element => { const formatDate = (date: Date): string => { @@ -347,9 +377,7 @@ const ResponsiveDataTable = ({ } }); updateCols && updateCols([...columns]); - - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [columnVisibility, updateCols]); + }, [columnVisibility, updateCols, columns]); React.useEffect(() => { updateColumnsEffect(); @@ -360,8 +388,16 @@ const ResponsiveDataTable = ({ Checkbox: Checkbox }; + const finalTheme = (baseTheme: Theme) => { + const defaultTheme = dataTableTheme(baseTheme, backgroundColor); + if (theme) { + return createTheme(defaultTheme, typeof theme === 'function' ? theme(baseTheme) : theme); + } + return defaultTheme; + }; + return ( - + Date: Mon, 11 Nov 2024 12:40:55 +0530 Subject: [PATCH 07/12] fix: issue in the catalog design table Signed-off-by: Amit Amrutiya --- .../CatalogDesignTable/CatalogDesignTable.tsx | 84 ++++++++++++++----- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/src/custom/CatalogDesignTable/CatalogDesignTable.tsx b/src/custom/CatalogDesignTable/CatalogDesignTable.tsx index c02c8f69..8808b42d 100644 --- a/src/custom/CatalogDesignTable/CatalogDesignTable.tsx +++ b/src/custom/CatalogDesignTable/CatalogDesignTable.tsx @@ -1,12 +1,17 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import _ from 'lodash'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; +import { PublishIcon } from '../../icons'; +import { CHARCOAL, useTheme } from '../../theme'; import { Pattern } from '../CustomCatalog/CustomCard'; import { useWindowDimensions } from '../Helpers/Dimension'; +import PromptComponent from '../Prompt'; +import { PromptRef } from '../Prompt/promt-component'; import ResponsiveDataTable from '../ResponsiveDataTable'; +import UnpublishTooltipIcon from './UnpublishTooltipIcon'; interface CatalogDesignsTableProps { - patters: Pattern[]; + patterns: Pattern[]; filter: any; columns: Array; totalCount: number; @@ -17,11 +22,17 @@ interface CatalogDesignsTableProps { page: number; setPage: (page: number) => void; columnVisibility: Record; - colViews: any; + colViews: Record | undefined; + handleBulkDeleteModal: (patterns: Pattern[], modalRef: React.RefObject) => void; + handleBulkpatternsDataUnpublishModal: ( + selected: any, + patterns: Pattern[], + modalRef: React.RefObject + ) => void; } export const CatalogDesignsTable: React.FC = ({ - patters, + patterns, filter, columns = [], totalCount = 0, @@ -32,12 +43,15 @@ export const CatalogDesignsTable: React.FC = ({ page = 0, setPage, columnVisibility = {}, - colViews = {} + colViews = {}, + handleBulkDeleteModal, + handleBulkpatternsDataUnpublishModal }) => { const [tableCols, updateCols] = useState>([]); const { width } = useWindowDimensions(); const smallScreen = width <= 360; - // const modalRef = useRef(null); + const theme = useTheme(); + const modalRef = useRef(null); useEffect(() => { if (Array.isArray(columns) && columns.length > 0) { @@ -45,7 +59,7 @@ export const CatalogDesignsTable: React.FC = ({ } }, [columns]); - const options = { + const options: any = { selectableRows: _.isNil(filter) ? 'none' : 'multiple', serverSide: true, filterType: 'multiselect', @@ -54,15 +68,12 @@ export const CatalogDesignsTable: React.FC = ({ rowsPerPage: pageSize, page, elevation: 0, - search: false, - filter: false, - download: false, - print: false, - viewColumns: false, onTableChange: (action: string, tableState: any) => { const sortInfo = tableState.announceText ? tableState.announceText.split(' : ') : []; let order = ''; - + if (tableState.activeColumn) { + order = `${columns[tableState.activeColumn].name} desc`; + } switch (action) { case 'changePage': setPage(tableState.page); @@ -90,20 +101,49 @@ export const CatalogDesignsTable: React.FC = ({ } }; + if (_.isNil(filter)) { + options.customToolbarSelect = (selected: any) => ( + handleBulkpatternsDataUnpublishModal(selected, patterns, modalRef)} + iconType="publish" + id={'unpublish-button'} + > + + + ); + } else { + options.onRowsDelete = (rowsDeleted: any) => { + const selectedPatterns = rowsDeleted.data.map(({ dataIndex }: any) => patterns[dataIndex]); + handleBulkDeleteModal(selectedPatterns, modalRef); + return false; + }; + } + if (!Array.isArray(tableCols) || tableCols.length === 0) { return null; } return ( - Object.values(pattern)) ?? []} - options={options} - colViews={colViews} - tableCols={tableCols} - updateCols={updateCols} - columnVisibility={columnVisibility} - /> + <> + + + ); }; From 6adbd53c5e52a876d6f4c1ec1eac5144cbe1c445 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 11 Nov 2024 13:29:00 +0530 Subject: [PATCH 08/12] feat: add new icon Signed-off-by: Amit Amrutiya --- .../UnpublishTooltipIcon.tsx | 53 +++++++++++++++++++ src/icons/GridView/GridViewIcon.tsx | 31 +++++++++++ src/icons/TableView/TableViewIcon.tsx | 31 +++++++++++ 3 files changed, 115 insertions(+) create mode 100644 src/custom/CatalogDesignTable/UnpublishTooltipIcon.tsx create mode 100644 src/icons/GridView/GridViewIcon.tsx create mode 100644 src/icons/TableView/TableViewIcon.tsx diff --git a/src/custom/CatalogDesignTable/UnpublishTooltipIcon.tsx b/src/custom/CatalogDesignTable/UnpublishTooltipIcon.tsx new file mode 100644 index 00000000..69b9deb2 --- /dev/null +++ b/src/custom/CatalogDesignTable/UnpublishTooltipIcon.tsx @@ -0,0 +1,53 @@ +import { ReactNode } from 'react'; +import { IconButton } from '../../base'; +import { useTheme } from '../../theme'; +import { HOVER_DELETE } from '../../theme/colors/colors'; +import { CustomTooltip } from '../CustomTooltip'; +import { IconWrapper } from '../ResponsiveDataTable'; + +interface UnpublishTooltipIconProps { + children: ReactNode; + onClick: () => void; + title: string; + iconType: 'delete' | 'publish'; + id: string; + style?: object; + placement?: 'bottom' | 'top' | 'left' | 'right'; + disabled?: boolean; +} + +function UnpublishTooltipIcon({ + children, + onClick, + title, + iconType, + id, + style, + placement, + disabled = false +}: UnpublishTooltipIconProps) { + const theme = useTheme(); + return ( + + + + {children} + + + + ); +} + +export default UnpublishTooltipIcon; diff --git a/src/icons/GridView/GridViewIcon.tsx b/src/icons/GridView/GridViewIcon.tsx new file mode 100644 index 00000000..049d05f9 --- /dev/null +++ b/src/icons/GridView/GridViewIcon.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +interface GridViewIconProps { + width?: string; + height?: string; + fill?: string; + opacity?: number; + style?: React.CSSProperties; +} + +export const GridViewIcon: React.FC = ({ + width = '24', + height = '28.8', + fill, + opacity, + style = {} +}) => ( + + + +); + +export default GridViewIcon; diff --git a/src/icons/TableView/TableViewIcon.tsx b/src/icons/TableView/TableViewIcon.tsx new file mode 100644 index 00000000..6bd33018 --- /dev/null +++ b/src/icons/TableView/TableViewIcon.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +interface TableViewIconProps { + width?: string; + height?: string; + fill?: string; + opacity?: number; + style?: React.CSSProperties; +} + +export const TableViewIcon: React.FC = ({ + width = '24', + height = '28.8', + fill, + opacity, + style = {} +}) => ( + + + +); + +export default TableViewIcon; From 14457f05d837fe15993d2ea12646b419f6c84acf Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 11 Nov 2024 13:29:49 +0530 Subject: [PATCH 09/12] feat: add CatalogTableVisibilityControl and ViewSwitch components for view toggling Signed-off-by: Amit Amrutiya --- .../CatalogTableVisibilityControl.tsx | 41 ++++++++++++ src/custom/CatalogDesignTable/ViewSwitch.tsx | 66 +++++++++++++++++++ src/custom/index.tsx | 2 +- 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/custom/CatalogDesignTable/CatalogTableVisibilityControl.tsx create mode 100644 src/custom/CatalogDesignTable/ViewSwitch.tsx diff --git a/src/custom/CatalogDesignTable/CatalogTableVisibilityControl.tsx b/src/custom/CatalogDesignTable/CatalogTableVisibilityControl.tsx new file mode 100644 index 00000000..600ac007 --- /dev/null +++ b/src/custom/CatalogDesignTable/CatalogTableVisibilityControl.tsx @@ -0,0 +1,41 @@ +import React, { Dispatch, SetStateAction } from 'react'; +import { CustomColumnVisibilityControl } from '../CustomColumnVisibilityControl'; +import { CustomColumn } from '../CustomColumnVisibilityControl/CustomColumnVisibilityControl'; +import { ViewSwitch } from './ViewSwitch'; + +type TypeView = 'grid' | 'table'; + +interface CatalogTableVisibilityControlProps { + viewType: TypeView; + setViewType: (view: TypeView) => void; + filteredColumns: CustomColumn[]; + columnVisibility: Record; + setColumnVisibility: Dispatch>>; + viewSwitchDisabled?: boolean; +} + +export const CatalogTableVisibilityControl: React.FC = ({ + viewType, + setViewType, + filteredColumns, + columnVisibility, + setColumnVisibility, + viewSwitchDisabled = false +}) => { + return ( +
+ {viewType !== 'grid' && ( + + )} + +
+ ); +}; diff --git a/src/custom/CatalogDesignTable/ViewSwitch.tsx b/src/custom/CatalogDesignTable/ViewSwitch.tsx new file mode 100644 index 00000000..7ac8a1a2 --- /dev/null +++ b/src/custom/CatalogDesignTable/ViewSwitch.tsx @@ -0,0 +1,66 @@ +/** + * Renders a switch component for toggling between grid and table view. + * + * @typedef {("grid" | "table")} TypeView + * @typedef {object} Props + * @prop {TypeView} props.view - The current view type ("grid" or "table"). + * @prop {Function} props.changeView - The function to change the view type. + */ + +import { IconButton } from '@mui/material'; +import { GridViewIcon, TableViewIcon } from '../../icons'; +import { useTheme } from '../../theme'; +import { CustomTooltip } from '../CustomTooltip'; + +type TypeView = 'grid' | 'table'; + +interface ViewSwitchProps { + view: TypeView; + changeView: (view: TypeView) => void; + height?: string; + style?: React.CSSProperties; + disabled?: boolean; +} + +export const ViewSwitch: React.FC = ({ + view, + changeView, + height = '3rem', + style = {}, + disabled = false +}) => { + const handleClick = () => { + changeView(view === 'grid' ? 'table' : 'grid'); + }; + + const Icon = view === 'grid' ? TableViewIcon : GridViewIcon; + const label = view === 'grid' ? 'Table View' : 'Grid View'; + const theme = useTheme(); + + return ( + + + + + + + + ); +}; diff --git a/src/custom/index.tsx b/src/custom/index.tsx index ed6517cc..1918d175 100644 --- a/src/custom/index.tsx +++ b/src/custom/index.tsx @@ -44,7 +44,6 @@ import { TransferList } from './TransferModal/TransferList'; import { TransferListProps } from './TransferModal/TransferList/TransferList'; import UniversalFilter, { UniversalFilterProps } from './UniversalFilter'; export { CatalogCard } from './CatalogCard'; -export { CatalogDesignsTable, colViews, createDesignColumns } from './CatalogDesignTable'; export { CatalogFilterSidebar } from './CatalogFilterSection'; export type { FilterListType } from './CatalogFilterSection'; export { StyledChartDialog } from './ChartDialog'; @@ -133,6 +132,7 @@ export type { UniversalFilterProps }; +export * from './CatalogDesignTable'; export * from './CatalogDetail'; export * from './Dialog'; export * from './permissions'; From 721c1b5fa318538bdece1237027f8ffa7299e92f Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 11 Nov 2024 13:30:09 +0530 Subject: [PATCH 10/12] feat: export GridViewIcon and TableViewIcon components; update CatalogDesignTable exports Signed-off-by: Amit Amrutiya --- src/custom/CatalogDesignTable/index.ts | 2 ++ src/icons/GridView/index.ts | 1 + src/icons/TableView/index.ts | 1 + src/icons/index.ts | 2 ++ 4 files changed, 6 insertions(+) create mode 100644 src/icons/GridView/index.ts create mode 100644 src/icons/TableView/index.ts diff --git a/src/custom/CatalogDesignTable/index.ts b/src/custom/CatalogDesignTable/index.ts index 50831504..ac46c7b5 100644 --- a/src/custom/CatalogDesignTable/index.ts +++ b/src/custom/CatalogDesignTable/index.ts @@ -1,3 +1,5 @@ import CatalogDesignsTable from './CatalogDesignTable'; import { colViews, createDesignColumns } from './columnConfig'; +export { CatalogTableVisibilityControl } from './CatalogTableVisibilityControl'; +export { ViewSwitch } from './ViewSwitch'; export { CatalogDesignsTable, colViews, createDesignColumns }; diff --git a/src/icons/GridView/index.ts b/src/icons/GridView/index.ts new file mode 100644 index 00000000..43f10c66 --- /dev/null +++ b/src/icons/GridView/index.ts @@ -0,0 +1 @@ +export { default as GridViewIcon } from './GridViewIcon'; diff --git a/src/icons/TableView/index.ts b/src/icons/TableView/index.ts new file mode 100644 index 00000000..742c6658 --- /dev/null +++ b/src/icons/TableView/index.ts @@ -0,0 +1 @@ +export { default as TableViewIcon } from './TableViewIcon'; diff --git a/src/icons/index.ts b/src/icons/index.ts index 6a4bc8df..22a3a721 100644 --- a/src/icons/index.ts +++ b/src/icons/index.ts @@ -53,6 +53,7 @@ export * from './EmptyStyle'; export * from './Environment'; export * from './ExternalLink'; export * from './Feedback'; +export * from './GridView'; export * from './HelpIcon'; export * from './Idea'; export * from './InfoOutlined'; @@ -88,6 +89,7 @@ export * from './Share'; export * from './SocialMedial'; export * from './Star'; export * from './Success'; +export * from './TableView'; export * from './TerminalIcon'; export * from './Toolkit'; export * from './Touch'; From a848b333e6e8c77a687da2d5405fc93b1138fea8 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 11 Nov 2024 14:06:42 +0530 Subject: [PATCH 11/12] chore: update name Signed-off-by: Amit Amrutiya --- ...gTableVisibilityControl.tsx => TableVisibilityControl.tsx} | 4 ++-- src/custom/CatalogDesignTable/index.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/custom/CatalogDesignTable/{CatalogTableVisibilityControl.tsx => TableVisibilityControl.tsx} (89%) diff --git a/src/custom/CatalogDesignTable/CatalogTableVisibilityControl.tsx b/src/custom/CatalogDesignTable/TableVisibilityControl.tsx similarity index 89% rename from src/custom/CatalogDesignTable/CatalogTableVisibilityControl.tsx rename to src/custom/CatalogDesignTable/TableVisibilityControl.tsx index 600ac007..a153aa0c 100644 --- a/src/custom/CatalogDesignTable/CatalogTableVisibilityControl.tsx +++ b/src/custom/CatalogDesignTable/TableVisibilityControl.tsx @@ -5,7 +5,7 @@ import { ViewSwitch } from './ViewSwitch'; type TypeView = 'grid' | 'table'; -interface CatalogTableVisibilityControlProps { +interface TableVisibilityControlProps { viewType: TypeView; setViewType: (view: TypeView) => void; filteredColumns: CustomColumn[]; @@ -14,7 +14,7 @@ interface CatalogTableVisibilityControlProps { viewSwitchDisabled?: boolean; } -export const CatalogTableVisibilityControl: React.FC = ({ +export const TableVisibilityControl: React.FC = ({ viewType, setViewType, filteredColumns, diff --git a/src/custom/CatalogDesignTable/index.ts b/src/custom/CatalogDesignTable/index.ts index ac46c7b5..fcab0208 100644 --- a/src/custom/CatalogDesignTable/index.ts +++ b/src/custom/CatalogDesignTable/index.ts @@ -1,5 +1,5 @@ import CatalogDesignsTable from './CatalogDesignTable'; import { colViews, createDesignColumns } from './columnConfig'; -export { CatalogTableVisibilityControl } from './CatalogTableVisibilityControl'; +export { TableVisibilityControl } from './TableVisibilityControl'; export { ViewSwitch } from './ViewSwitch'; export { CatalogDesignsTable, colViews, createDesignColumns }; From 8cf6f9d4dcad4c42bff11106390cbbea5bfe019e Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 11 Nov 2024 15:37:51 +0530 Subject: [PATCH 12/12] fix: theme issue Signed-off-by: Amit Amrutiya --- .../CatalogDesignTable/columnConfig.tsx | 14 +++++------ src/custom/CustomTooltip/customTooltip.tsx | 2 +- src/custom/ResponsiveDataTable.tsx | 24 ++++++++++++------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/custom/CatalogDesignTable/columnConfig.tsx b/src/custom/CatalogDesignTable/columnConfig.tsx index ce5feceb..d46f4404 100644 --- a/src/custom/CatalogDesignTable/columnConfig.tsx +++ b/src/custom/CatalogDesignTable/columnConfig.tsx @@ -84,7 +84,6 @@ export const createDesignColumns = ({ }: ColumnConfigProps): MUIDataTableColumn[] => { const cleanedType = type?.replace('my-', '').replace(/s$/, ''); const getColumnValue = (tableMeta: MUIDataTableMeta, targetColumn: string): any => { - console.log('amitas targetColumn', tableMeta); //@ts-ignore const rowData = tableMeta.tableData[tableMeta.rowIndex] as Pattern; return (rowData as any)[targetColumn] || ''; @@ -290,13 +289,12 @@ export const createDesignColumns = ({ }'s design "${rowData?.name}" on Layer5's Catalog`; } } - const baseActions: ActionItem[] = [ { title: 'Clone', onClick: () => handleCloneClick(rowData), disabled: isCloneDisabled, - icon: + icon: }, { title: 'Download', @@ -305,12 +303,12 @@ export const createDesignColumns = ({ ? downloadFilter(rowData.id, rowData.name) : downloadYaml(rowData.pattern_file, rowData.name); }, - icon: + icon: }, { title: 'Copy Link', onClick: () => handleCopyUrl(rowData), - icon: + icon: }, { title: 'Share Design via Socials', @@ -348,7 +346,7 @@ export const createDesignColumns = ({ { title: 'Open in playground', onClick: () => handleOpenPlayground(rowData), - icon: + icon: } ]; // TODO: make this unbpublish action work for playgroud @@ -359,14 +357,14 @@ export const createDesignColumns = ({ title: 'Unpublish', onClick: () => handleUnpublish(rowData), disabled: isUnpublishDisabled, - icon: + icon: }, ...baseActions.slice(2) ] : baseActions; //@ts-ignore - return ; + return ; } } } diff --git a/src/custom/CustomTooltip/customTooltip.tsx b/src/custom/CustomTooltip/customTooltip.tsx index 7287c152..b18cb18e 100644 --- a/src/custom/CustomTooltip/customTooltip.tsx +++ b/src/custom/CustomTooltip/customTooltip.tsx @@ -57,7 +57,7 @@ function CustomTooltip({ onClick={onClick} {...props} > - {children} + {children} ); } diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index c1e79b53..235ec5e9 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -4,7 +4,6 @@ import React, { useCallback } from 'react'; import { Checkbox, Collapse, ListItemIcon, ListItemText, Menu, MenuItem } from '../base'; import { ShareIcon } from '../icons'; import { EllipsisIcon } from '../icons/Ellipsis'; -import { useTheme } from '../theme'; import TooltipIcon from './TooltipIcon'; export const IconWrapper = styled('div')<{ disabled?: boolean }>(({ disabled = false }) => ({ @@ -18,7 +17,8 @@ export const IconWrapper = styled('div')<{ disabled?: boolean }>(({ disabled = f export const DataTableEllipsisMenu: React.FC<{ actionsList: NonNullable['actionsList']; -}> = ({ actionsList }) => { + theme?: Theme; +}> = ({ actionsList, theme }) => { const [anchorEl, setAnchorEl] = React.useState(null); const [isSocialShareOpen, setIsSocialShareOpen] = React.useState(false); @@ -41,13 +41,13 @@ export const DataTableEllipsisMenu: React.FC<{ handleClose(); } }; - const theme = useTheme(); + return ( <> } + icon={} arrow /> @@ -75,9 +75,15 @@ export const DataTableEllipsisMenu: React.FC<{ disabled={action.disabled} > - + - {action.title} + + {action.title} + , {action.icon} - {action.title} + + {action.title} + );