Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert workspace data table into sistent component #823

Merged
merged 20 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
188aaf4
feat: convert design column config into sistent component
amitamrutiya Nov 22, 2024
99e9cf8
feat: convert workspaces assignment modal into sistent component
amitamrutiya Nov 22, 2024
37933af
feat: add EditButton component with custom tooltip and styled icon
amitamrutiya Nov 22, 2024
a2c111e
feat: add useDesignAssignment hook for managing design assignments in…
amitamrutiya Nov 22, 2024
eb5108b
feat: update column view types to use ColView interface across Catalo…
amitamrutiya Nov 22, 2024
3e5764e
feat: add DesignTable component for managing workspace designs
amitamrutiya Nov 22, 2024
e797e5e
feat: introduce EnvironmentTable component and enhance design table f…
amitamrutiya Nov 22, 2024
4194842
feat: add LogoutIcon and TeamsIcon components with customizable prope…
amitamrutiya Nov 25, 2024
bfc74c3
feat: add GithubIcon and GoogleIcon components with customizable prop…
amitamrutiya Nov 23, 2024
7d13fcf
feat: enhance TooltipIcon component with additional props and improve…
amitamrutiya Nov 23, 2024
72326bc
feat: enhance CatalogDesignTable with search functionality and improv…
amitamrutiya Nov 23, 2024
f74e18d
feat: add FormatId component for displaying and copying truncated IDs
amitamrutiya Nov 23, 2024
00225a9
feat: add TeamTable component for managing team members with expandab…
amitamrutiya Nov 24, 2024
88ca492
feat: add UsersTable and TooltipIconButton components with customizab…
amitamrutiya Nov 24, 2024
487e4fd
feat: implement useTeamAssignment hook for managing team assignments …
amitamrutiya Nov 24, 2024
bbb0588
feat: update AssignmentModal and EnvironmentTable to use isAssignAllowed
amitamrutiya Nov 25, 2024
6765d63
feat: remove TooltipIcon component and add helper functions for times…
amitamrutiya Nov 25, 2024
be19b85
feat: update sorting configurations and add user_id column in design …
amitamrutiya Nov 25, 2024
fc59b7f
fix: types
amitamrutiya Nov 26, 2024
034da1f
Merge branch 'master' into amit/workspace-sistent
amitamrutiya Nov 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ export const CARIBBEAN_GREEN_FILL = '#00D3A9';
export const DEFAULT_STROKE = '#000';
export const DEFAULT_STROKE_WIDTH = '2';
export const CLOUD_URL = 'https://cloud.layer5.io';
export const PLAYGROUND_MODES = {
DESIGNER: 'design',
OPERATOR: 'operator'
} as const;
22 changes: 17 additions & 5 deletions src/custom/CatalogDesignTable/CatalogDesignTable.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import _ from 'lodash';
import { MUIDataTableColumn } from 'mui-datatables';
import { useCallback, useMemo, useRef } from 'react';
import { PublishIcon } from '../../icons';
import { CHARCOAL, useTheme } from '../../theme';
import { Pattern } from '../CustomCatalog/CustomCard';
import { ErrorBoundary } from '../ErrorBoundary';
import { ColView } from '../Helpers/ResponsiveColumns/responsive-coulmns.tsx/responsive-column';
import PromptComponent from '../Prompt';
import { PromptRef } from '../Prompt/promt-component';
import ResponsiveDataTable from '../ResponsiveDataTable';
Expand All @@ -13,7 +15,7 @@ import UnpublishTooltipIcon from './UnpublishTooltipIcon';
interface CatalogDesignsTableProps {
patterns: Pattern[];
filter: any;
columns: Array<any>;
columns: MUIDataTableColumn[];
totalCount: number;
sortOrder: string;
setSortOrder: (order: string) => void;
Expand All @@ -22,8 +24,9 @@ interface CatalogDesignsTableProps {
page: number;
setPage: (page: number) => void;
columnVisibility: Record<string, boolean>;
colViews: Record<string, boolean> | undefined;
colViews: ColView[];
handleBulkDeleteModal: (patterns: Pattern[], modalRef: React.RefObject<PromptRef>) => void;
setSearch?: (search: string) => void;
handleBulkpatternsDataUnpublishModal: (
selected: any,
patterns: Pattern[],
Expand All @@ -43,8 +46,9 @@ export const CatalogDesignsTable: React.FC<CatalogDesignsTableProps> = ({
page = 0,
setPage,
columnVisibility = {},
colViews = {},
colViews = [],
handleBulkDeleteModal,
setSearch,
handleBulkpatternsDataUnpublishModal
}) => {
const theme = useTheme();
Expand All @@ -60,7 +64,7 @@ export const CatalogDesignsTable: React.FC<CatalogDesignsTableProps> = ({
return new Date(date).toLocaleDateString('en-US', dateOptions);
}, []);

const processedColumns = useMemo(() => {
const processedColumns: MUIDataTableColumn[] = useMemo(() => {
return columns.map((col) => {
const newCol = { ...col };
if (!newCol.options) newCol.options = {};
Expand Down Expand Up @@ -105,6 +109,9 @@ export const CatalogDesignsTable: React.FC<CatalogDesignsTableProps> = ({
case 'changeRowsPerPage':
setPageSize(tableState.rowsPerPage);
break;
case 'search':
setSearch && setSearch(tableState.searchText !== null ? tableState.searchText : '');
break;
case 'sort':
if (
sortInfo.length === 2 &&
Expand All @@ -123,7 +130,7 @@ export const CatalogDesignsTable: React.FC<CatalogDesignsTableProps> = ({
break;
}
},
[columns, setPage, setPageSize, setSortOrder, sortOrder]
[columns, setPage, setSearch, setPageSize, setSortOrder, sortOrder]
);

const options = useMemo(
Expand All @@ -136,6 +143,11 @@ export const CatalogDesignsTable: React.FC<CatalogDesignsTableProps> = ({
rowsPerPage: pageSize,
page,
elevation: 0,
sortOrder: {
name: 'updated_at',
direction: 'desc'
},

onTableChange: handleTableChange,
customToolbarSelect: _.isNil(filter)
? (selected: any) => (
Expand Down
236 changes: 236 additions & 0 deletions src/custom/CatalogDesignTable/DesignTableColumnConfig.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
import { MUIDataTableColumn, MUIDataTableMeta } from 'mui-datatables';
import { PLAYGROUND_MODES } from '../../constants/constants';
import { ChainIcon, CopyIcon, KanvasIcon, PublishIcon } from '../../icons';
import Download from '../../icons/Download/Download';
import { CHARCOAL } from '../../theme';
import { downloadYaml, slugify } from '../CatalogDetail/helper';
import { RESOURCE_TYPES } from '../CatalogDetail/types';
import { Pattern } from '../CustomCatalog/CustomCard';
import { ConditionalTooltip } from '../Helpers/CondtionalTooltip';
import { ColView } from '../Helpers/ResponsiveColumns/responsive-coulmns.tsx';
import { DataTableEllipsisMenu } from '../ResponsiveDataTable';
import AuthorCell from './AuthorCell';
import { getColumnValue } from './helper';
import { L5DeleteIcon, NameDiv } from './style';

interface TableMeta extends MUIDataTableMeta {
rowIndex: number;
tableData: Pattern[];
}

interface ColumnConfigProps {
handleDeleteModal: (data: Pattern) => () => void;
handlePublishModal: (data: Pattern) => void;
handleUnpublishModal: (data: Pattern) => () => void;
handleCopyUrl: (type: string, name: string, id: string) => void;
handleClone: (name: string, id: string) => void;
handleShowDetails: (designId: string, designName: string) => void;
isDownloadAllowed: boolean;
isCopyLinkAllowed: boolean;
isDeleteAllowed: boolean;
isPublishAllowed: boolean;
isUnpublishAllowed: boolean;
// for workspace designs table page only
isFromWorkspaceTable?: boolean;
isRemoveAllowed?: boolean;
}

export const colViews: ColView[] = [
['id', 'na'],
['name', 'xs'],
['first_name', 'xs'],
['created_at', 'na'],
['updated_at', 'l'],
['visibility', 'l'],
['user_id', 'na'],
['actions', 'xs']
];

export const createDesignsColumnsConfig = ({
handleDeleteModal,
handlePublishModal,
handleUnpublishModal,
handleCopyUrl,
handleClone,
handleShowDetails,
isUnpublishAllowed,
isCopyLinkAllowed,
isDeleteAllowed,
isPublishAllowed,
isDownloadAllowed,
isRemoveAllowed,
isFromWorkspaceTable = false
}: ColumnConfigProps): MUIDataTableColumn[] => {
return [
{
name: 'id',
label: 'ID',
options: {
filter: false,
customBodyRender: (value: string) => <ConditionalTooltip value={value} maxLength={10} />
}
},
{
name: 'name',
label: 'Pattern Name',
options: {
filter: false,
sort: true,
searchable: true,
customBodyRender: (value: string, tableMeta: MUIDataTableMeta) => {
const designId = (tableMeta as TableMeta).tableData[tableMeta.rowIndex]?.id ?? '';
const designName = (tableMeta as TableMeta).tableData[tableMeta.rowIndex]?.name ?? '';

return <NameDiv onClick={() => handleShowDetails(designId, designName)}>{value}</NameDiv>;
}
}
},
{
name: 'first_name',
label: 'Author',
options: {
filter: false,
sort: true,
searchable: true,
customBodyRender: (_, tableMeta: MUIDataTableMeta) => {
const firstName = getColumnValue(tableMeta as TableMeta, 'first_name');
const lastName = getColumnValue(tableMeta as TableMeta, 'last_name');
const avatar_url = getColumnValue(tableMeta as TableMeta, 'avatar_url');
const user_id = getColumnValue(tableMeta as TableMeta, 'user_id');

return (
<AuthorCell
firstName={firstName}
lastName={lastName}
avatarUrl={avatar_url}
userId={user_id}
/>
);
}
}
},
{
name: 'created_at',
label: 'Created At',
options: {
filter: false,
sort: true,
searchable: true,
setCellHeaderProps: () => {
return { align: 'center' };
}
}
},
{
name: 'updated_at',
label: 'Updated At',
options: {
filter: false,
sort: true,
searchable: true,
setCellHeaderProps: () => {
return { align: 'center' };
}
}
},
{
name: 'visibility',
label: 'Visibility',
options: {
filter: false,
sort: false,
searchable: true
}
},
{
name: 'user_id',
label: 'User ID',
options: {
filter: false,
sort: false,
searchable: false
}
},
{
name: 'actions',
label: 'Actions',
options: {
filter: false,
sort: false,
searchable: false,
setCellHeaderProps: () => ({ align: 'center' as const }),
setCellProps: () => ({ align: 'center' as const }),
customBodyRender: function CustomBody(_, tableMeta: MUIDataTableMeta) {
const rowIndex = (tableMeta as TableMeta).rowIndex;
const rowData = (tableMeta as TableMeta).tableData[rowIndex];

const actionsList = [
{
title: 'Download',
onClick: () => downloadYaml(rowData?.pattern_file, rowData?.name),
disabled: !isDownloadAllowed,
icon: <Download width={24} height={24} fill={CHARCOAL} />
},
{
title: 'Copy Link',
disabled: rowData.visibility === 'private' || !isCopyLinkAllowed,
onClick: () => {
handleCopyUrl(RESOURCE_TYPES.DESIGNS, rowData?.name, rowData?.id);
},
icon: <ChainIcon width={'24'} height={'24'} fill={CHARCOAL} />
},
{
title: 'Open in playground',
onClick: () => {
window.open(
`https://playground.meshery.io/extension/meshmap?mode=${
PLAYGROUND_MODES.DESIGNER
}&type=${RESOURCE_TYPES.DESIGNS}&id=${rowData?.id}&name=${slugify(
rowData?.name
)}`,
'_blank'
);
},
icon: <KanvasIcon width={24} height={24} primaryFill={CHARCOAL} />
},
{
title: isFromWorkspaceTable ? 'Remove Design' : 'Delete',
disabled: isFromWorkspaceTable ? !isRemoveAllowed : !isDeleteAllowed,
onClick: () => handleDeleteModal(rowData)(),
icon: <L5DeleteIcon />
}
];

const publishAction = {
title: 'Publish',
disabled: !isPublishAllowed,
onClick: () => handlePublishModal(rowData),
icon: <PublishIcon width={24} height={24} fill={CHARCOAL} />
};

const unpublishAction = {
title: 'Unpublish',
onClick: () => handleUnpublishModal(rowData)(),
disabled: !isUnpublishAllowed,
icon: <PublishIcon width={24} height={24} fill={CHARCOAL} />
};

const cloneAction = {
title: 'Clone',
onClick: () => handleClone(rowData?.name, rowData?.id),
icon: <CopyIcon width={24} height={24} fill={CHARCOAL} />
};

if (rowData.visibility === 'published') {
actionsList.splice(0, 0, cloneAction);
actionsList.splice(2, 0, unpublishAction);
} else {
actionsList.splice(1, 0, publishAction);
}

return <DataTableEllipsisMenu actionsList={actionsList} />;
}
}
}
];
};
10 changes: 2 additions & 8 deletions src/custom/CatalogDesignTable/columnConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import { downloadFilter, downloadYaml } from '../CatalogDetail/helper';
import { RESOURCE_TYPES } from '../CatalogDetail/types';
import { Pattern } from '../CustomCatalog/CustomCard';
import { ConditionalTooltip } from '../Helpers/CondtionalTooltip';
import { ColView } from '../Helpers/ResponsiveColumns/responsive-coulmns.tsx/responsive-column';
import { DataTableEllipsisMenu } from '../ResponsiveDataTable';
import AuthorCell from './AuthorCell';
import { getColumnValue } from './helper';
import { NameDiv } from './style';

export type ColView = [string, 'na' | 'xs' | 'l'];

export const colViews: ColView[] = [
['id', 'na'],
['name', 'xs'],
Expand Down Expand Up @@ -83,12 +83,6 @@ export const createDesignColumns = ({
showOpenPlayground
}: ColumnConfigProps): MUIDataTableColumn[] => {
const cleanedType = type?.replace('my-', '').replace(/s$/, '');
const getColumnValue = (tableMeta: MUIDataTableMeta, targetColumn: string): any => {
//@ts-ignore
const rowData = tableMeta.tableData[tableMeta.rowIndex] as Pattern;
return (rowData as any)[targetColumn] || '';
};

return [
{
name: 'id',
Expand Down
6 changes: 6 additions & 0 deletions src/custom/CatalogDesignTable/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

export const getColumnValue = (tableMeta: any, targetColumn: string): any => {
const rowData = tableMeta.tableData[tableMeta.rowIndex];
return (rowData as any)[targetColumn] || '';
};
13 changes: 12 additions & 1 deletion src/custom/CatalogDesignTable/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import AuthorCell from './AuthorCell';
import CatalogDesignsTable from './CatalogDesignTable';
import { colViews, createDesignColumns } from './columnConfig';
import {
createDesignsColumnsConfig,
colViews as designColumnsColViews
} from './DesignTableColumnConfig';
export { TableVisibilityControl } from './TableVisibilityControl';
export { ViewSwitch } from './ViewSwitch';
export { AuthorCell, CatalogDesignsTable, colViews, createDesignColumns };
export {
AuthorCell,
CatalogDesignsTable,
colViews,
createDesignColumns,
createDesignsColumnsConfig,
designColumnsColViews
};
Loading