From 65ef6303f61fbd3c3767c9ca53bf28bdf1ae8f46 Mon Sep 17 00:00:00 2001 From: Yash sharma <71271069+Yashsharma1911@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:03:57 +0530 Subject: [PATCH 01/66] Update publish modal schema Signed-off-by: Yash sharma <71271069+Yashsharma1911@users.noreply.github.com> --- src/schemas/publishCatalogItem/schema.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/schemas/publishCatalogItem/schema.tsx b/src/schemas/publishCatalogItem/schema.tsx index 9219fc2b..6c9b5ea3 100644 --- a/src/schemas/publishCatalogItem/schema.tsx +++ b/src/schemas/publishCatalogItem/schema.tsx @@ -24,14 +24,16 @@ const publishCatalogItemSchema = { description: 'Specific stipulations to consider and known behaviors to be aware of when using this design.', format: 'textarea', - 'x-rjsf-grid-area': 12 + 'x-rjsf-grid-area': 12, + "x-encode-in-uri": true }, pattern_info: { type: 'string', title: 'Description', description: 'Purpose of the design along with its intended and unintended uses.', format: 'textarea', - 'x-rjsf-grid-area': 12 + 'x-rjsf-grid-area': 12, + "x-encode-in-uri": true }, type: { type: 'string', From 0227adaeaf2bd41211203b71621a0e85755d3042 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Fri, 25 Oct 2024 11:59:41 +0530 Subject: [PATCH 02/66] feat: add component in the filter sidbar state Signed-off-by: Amit Amrutiya --- .../CatalogFilterSidebar.tsx | 14 +- .../CatalogFilterSidebarState.tsx | 47 ++++--- .../CatalogFilterSection/FilterSection.tsx | 120 ++++++++++-------- src/custom/CatalogFilterSection/index.tsx | 4 +- src/custom/index.tsx | 2 +- 5 files changed, 112 insertions(+), 75 deletions(-) diff --git a/src/custom/CatalogFilterSection/CatalogFilterSidebar.tsx b/src/custom/CatalogFilterSection/CatalogFilterSidebar.tsx index 965af08b..c3e36e9c 100644 --- a/src/custom/CatalogFilterSection/CatalogFilterSidebar.tsx +++ b/src/custom/CatalogFilterSection/CatalogFilterSidebar.tsx @@ -29,14 +29,24 @@ export interface FilterOption { export interface FilterList { filterKey: string; sectionDisplayName?: string; - options: FilterOption[]; defaultOpen?: boolean; isMultiSelect?: boolean; + options?: FilterOption[]; + customComponent?: React.ComponentType; } +type FilterListWithOptions = FilterList & { options: FilterOption[]; customComponent?: never }; + +type FilterListWithCustomComponent = FilterList & { + customComponent: React.ComponentType; + options?: never; +}; + +export type FilterListType = FilterListWithOptions | FilterListWithCustomComponent; + export interface CatalogFilterSidebarProps { setData: (callback: (prevFilters: FilterValues) => FilterValues) => void; - lists: FilterList[]; + lists: FilterListType[]; value?: FilterValues; styleProps?: StyleProps; } diff --git a/src/custom/CatalogFilterSection/CatalogFilterSidebarState.tsx b/src/custom/CatalogFilterSection/CatalogFilterSidebarState.tsx index 76b0d72d..1d2bb51b 100644 --- a/src/custom/CatalogFilterSection/CatalogFilterSidebarState.tsx +++ b/src/custom/CatalogFilterSection/CatalogFilterSidebarState.tsx @@ -1,7 +1,7 @@ import { useCallback, useState } from 'react'; import { CatalogFilterSidebarProps, - FilterList, + FilterListType, FilterValues, StyleProps } from './CatalogFilterSidebar'; @@ -16,7 +16,7 @@ import FilterSection from './FilterSection'; * @param {Object} styleProps - The style properties for the component. */ const CatalogFilterSidebarState: React.FC<{ - lists: FilterList[]; + lists: FilterListType[]; onApplyFilters: CatalogFilterSidebarProps['setData']; value: FilterValues; styleProps: StyleProps; @@ -78,19 +78,36 @@ const CatalogFilterSidebarState: React.FC<{ return ( <> - {lists.map((list) => ( - - ))} + {lists.map((list) => { + if (list.customComponent) { + return ( + + ); + } + + return ( + + ); + })} ); }; diff --git a/src/custom/CatalogFilterSection/FilterSection.tsx b/src/custom/CatalogFilterSection/FilterSection.tsx index 0696a6ed..4be5eddb 100644 --- a/src/custom/CatalogFilterSection/FilterSection.tsx +++ b/src/custom/CatalogFilterSection/FilterSection.tsx @@ -10,12 +10,13 @@ import { EndAdornmentText, FilterTitleButton } from './style'; interface FilterSectionProps { filterKey: string; sectionDisplayName?: string; - options: FilterOption[]; + options?: FilterOption[]; filters: FilterValues; openSections: Record; - onCheckboxChange: (filterKey: string, value: string, checked: boolean) => void; + onCheckboxChange?: (filterKey: string, value: string, checked: boolean) => void; onSectionToggle: (filterKey: string) => void; styleProps: StyleProps; + customComponent?: React.ComponentType; } /** @@ -33,12 +34,13 @@ interface FilterSectionProps { const FilterSection: React.FC = ({ filterKey, sectionDisplayName, - options, + options = [], filters, openSections, onCheckboxChange, onSectionToggle, - styleProps + styleProps, + customComponent: CustomComponent }) => { const [searchQuery, setSearchQuery] = useState(''); @@ -47,9 +49,10 @@ const FilterSection: React.FC = ({ }, []); const showSearch = options.length > 10; - const searchedOptions = searchQuery - ? options.filter((option) => option.label.toLowerCase().includes(searchQuery.toLowerCase())) - : options; + const searchedOptions = + searchQuery && options.length + ? options.filter((option) => option.label.toLowerCase().includes(searchQuery.toLowerCase())) + : options; return ( <> @@ -65,59 +68,66 @@ const FilterSection: React.FC = ({ {openSections[filterKey] ? : } - - {showSearch && ( - - Total : {searchedOptions.length ?? 0} - } - /> - - )} - {searchedOptions.map((option, index) => ( - - - + ) : ( + + {showSearch && ( + + Total : {searchedOptions.length ?? 0} } - onChange={(e) => onCheckboxChange(filterKey, option.value, e.target.checked)} - value={option.value} /> + + )} + {searchedOptions.map((option, index) => ( + + + + onCheckboxChange && + onCheckboxChange(filterKey, option.value, e.target.checked) + } + value={option.value} + /> - {option.Icon && } + {option.Icon && } - {option.label} + {option.label} + + + {option.totalCount !== undefined && `(${option.totalCount || 0})`} + {option.description && ( + + )} + - - {option.totalCount !== undefined && `(${option.totalCount || 0})`} - {option.description && ( - - )} - - - ))} - + ))} + + )} ); diff --git a/src/custom/CatalogFilterSection/index.tsx b/src/custom/CatalogFilterSection/index.tsx index a79660b9..5fb7338c 100644 --- a/src/custom/CatalogFilterSection/index.tsx +++ b/src/custom/CatalogFilterSection/index.tsx @@ -1,4 +1,4 @@ -import CatalogFilterSidebar, { FilterList } from './CatalogFilterSidebar'; +import CatalogFilterSidebar, { FilterListType } from './CatalogFilterSidebar'; export { CatalogFilterSidebar }; -export type { FilterList }; +export type { FilterListType }; diff --git a/src/custom/index.tsx b/src/custom/index.tsx index a7505ea5..ae5e6f82 100644 --- a/src/custom/index.tsx +++ b/src/custom/index.tsx @@ -45,7 +45,7 @@ import { TransferListProps } from './TransferModal/TransferList/TransferList'; import UniversalFilter, { UniversalFilterProps } from './UniversalFilter'; export { CatalogCard } from './CatalogCard'; export { CatalogFilterSidebar } from './CatalogFilterSection'; -export type { FilterList } from './CatalogFilterSection'; +export type { FilterListType } from './CatalogFilterSection'; export { StyledChartDialog } from './ChartDialog'; export { LearningContent } from './LearningContent'; export { NavigationNavbar } from './NavigationNavbar'; From 98b56ac23cd1d88bc717a711c28b65d6b3544eaa Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Tue, 29 Oct 2024 06:34:59 +0530 Subject: [PATCH 03/66] fix(error): boundary Signed-off-by: Sudhanshu Dasgupta --- src/custom/ErrorBoundary/ErrorBoundary.tsx | 53 ++++++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/custom/ErrorBoundary/ErrorBoundary.tsx b/src/custom/ErrorBoundary/ErrorBoundary.tsx index 51345307..6858e896 100644 --- a/src/custom/ErrorBoundary/ErrorBoundary.tsx +++ b/src/custom/ErrorBoundary/ErrorBoundary.tsx @@ -20,6 +20,8 @@ const StyledLink = styled(Link)(({ theme }) => ({ })); const CodeMessage = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', backgroundColor: theme.palette.background.code, color: theme.palette.text.tertiary, padding: '.85rem', @@ -30,14 +32,25 @@ const CodeMessage = styled('div')(({ theme }) => ({ interface FallbackComponentProps extends FallbackProps { resetErrorBoundary: () => void; children?: React.ReactNode; + pageUrl?: string; + timestamp?: string; } export function Fallback({ error, children }: FallbackComponentProps): JSX.Element { + const pageUrl = window.location.href; + const timestamp = new Date().toLocaleString(); return (

Uh-oh!😔 Please pardon the mesh.

- {(error as Error).message} + + Error: + {(error as Error).message} + +
+ URL: {pageUrl} +
+ Logged at: {timestamp}
We apologize for the inconvenience. The issue may be on our end. If troubleshooting doesn't @@ -56,18 +69,50 @@ export function Fallback({ error, children }: FallbackComponentProps): JSX.Eleme } const reportError = (error: Error, info: React.ErrorInfo): void => { + const pageUrl = window.location.href; + const timestamp = new Date().toLocaleString(); // This is where you'd send the error to Sentry, etc - console.log('Error Caught Inside Boundary --reportError', error, 'Info', info); + console.log( + 'Error Caught Inside Boundary --reportError', + error, + 'Info', + info, + 'Page URL:', + pageUrl, + 'Timestamp:', + timestamp + ); }; interface ErrorBoundaryProps { customFallback?: React.ComponentType; children: React.ReactNode; + onErrorCaught?: (error: string) => void; } -export const ErrorBoundary: React.FC = ({ customFallback, children }) => { +export const ErrorBoundary: React.FC = ({ + customFallback, + children, + onErrorCaught +}) => { + const pageUrl = window.location.href; + const timestamp = new Date().toLocaleString(); + + const handleError = (error: Error, info: React.ErrorInfo) => { + // Pass error message to onErrorCaught + onErrorCaught?.(error.message); + reportError(error, info); + }; + return ( - + + } + onError={handleError} + > {children} ); From 48885ccc75a6d88dd8078db4dbaf98142e45a630 Mon Sep 17 00:00:00 2001 From: Yash sharma <71271069+Yashsharma1911@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:14:01 +0000 Subject: [PATCH 04/66] fix: fix prettier issue Signed-off-by: Yash sharma <71271069+Yashsharma1911@users.noreply.github.com> --- src/schemas/publishCatalogItem/schema.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/schemas/publishCatalogItem/schema.tsx b/src/schemas/publishCatalogItem/schema.tsx index 6c9b5ea3..06295112 100644 --- a/src/schemas/publishCatalogItem/schema.tsx +++ b/src/schemas/publishCatalogItem/schema.tsx @@ -25,7 +25,7 @@ const publishCatalogItemSchema = { 'Specific stipulations to consider and known behaviors to be aware of when using this design.', format: 'textarea', 'x-rjsf-grid-area': 12, - "x-encode-in-uri": true + 'x-encode-in-uri': true }, pattern_info: { type: 'string', @@ -33,7 +33,7 @@ const publishCatalogItemSchema = { description: 'Purpose of the design along with its intended and unintended uses.', format: 'textarea', 'x-rjsf-grid-area': 12, - "x-encode-in-uri": true + 'x-encode-in-uri': true }, type: { type: 'string', From d5c394e5839e2a9b6a0f80b00055849b8a20605b Mon Sep 17 00:00:00 2001 From: Yash sharma <71271069+Yashsharma1911@users.noreply.github.com> Date: Fri, 1 Nov 2024 18:34:48 +0000 Subject: [PATCH 05/66] fix: reorder the fields Signed-off-by: Yash sharma <71271069+Yashsharma1911@users.noreply.github.com> --- src/schemas/publishCatalogItem/uiSchema.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schemas/publishCatalogItem/uiSchema.tsx b/src/schemas/publishCatalogItem/uiSchema.tsx index 646098bd..2e2e9f69 100644 --- a/src/schemas/publishCatalogItem/uiSchema.tsx +++ b/src/schemas/publishCatalogItem/uiSchema.tsx @@ -1,5 +1,5 @@ const publishCatalogItemUiSchema = { - 'ui:order': ['type', 'compatibility', 'pattern_caveats', 'pattern_info'] + 'ui:order': ['type', 'compatibility', 'pattern_info', 'pattern_caveats'] }; export default publishCatalogItemUiSchema; From cd01819c31d7ed00bdb6966f442015309a15aca2 Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Sat, 2 Nov 2024 16:52:04 +0530 Subject: [PATCH 06/66] feat(catalog): unpublish action Signed-off-by: Sudhanshu Dasgupta --- src/custom/CatalogDetail/ActionButton.tsx | 29 ++++++++++++++++++++--- src/custom/CatalogDetail/style.tsx | 16 +++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/custom/CatalogDetail/ActionButton.tsx b/src/custom/CatalogDetail/ActionButton.tsx index ed7ce790..8d000e1d 100644 --- a/src/custom/CatalogDetail/ActionButton.tsx +++ b/src/custom/CatalogDetail/ActionButton.tsx @@ -1,12 +1,12 @@ import _ from 'lodash'; import React from 'react'; import { CircularProgress } from '../../base'; -import { CopyIcon, KanvasIcon } from '../../icons'; +import { CopyIcon, KanvasIcon, PublishIcon } from '../../icons'; import Download from '../../icons/Download/Download'; import { charcoal } from '../../theme'; import { Pattern } from '../CustomCatalog/CustomCard'; import { downloadFilter, downloadYaml, slugify } from './helper'; -import { ActionButton, LinkUrl, StyledActionWrapper } from './style'; +import { ActionButton, LinkUrl, StyledActionWrapper, UnpublishAction } from './style'; import { RESOURCE_TYPES } from './types'; interface ActionButtonsProps { @@ -17,8 +17,10 @@ interface ActionButtonsProps { isCloneLoading: boolean; handleClone: (name: string, id: string) => void; mode: string; + handleUnpublish?: () => void; isCloneDisabled: boolean; showOpenPlaygroundButton: boolean; + showUnpublishAction: boolean; } const ActionButtons: React.FC = ({ @@ -30,7 +32,9 @@ const ActionButtons: React.FC = ({ handleClone, mode, isCloneDisabled, - showOpenPlaygroundButton + showOpenPlaygroundButton, + showUnpublishAction, + handleUnpublish }) => { const cleanedType = type.replace('my-', '').replace(/s$/, ''); const resourcePlaygroundType = Object.values({ @@ -112,6 +116,25 @@ const ActionButtons: React.FC = ({ )} + {showUnpublishAction && ( + + + + Unpublish + + + )} ); }; diff --git a/src/custom/CatalogDetail/style.tsx b/src/custom/CatalogDetail/style.tsx index 5d632025..81867492 100644 --- a/src/custom/CatalogDetail/style.tsx +++ b/src/custom/CatalogDetail/style.tsx @@ -39,6 +39,22 @@ export const ActionButton = styled('div')(({ disabled = false flex: '1' })); +export const UnpublishAction = styled('div')(({ disabled = false, theme }) => ({ + cursor: disabled ? 'not-allowed' : 'pointer', + opacity: disabled ? '0.5' : '1', + textAlign: 'center', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + borderRadius: '0.5rem', + backgroundColor: 'transparent', + border: theme.palette.border.default, + padding: '0.5rem', + color: theme.palette.text.default, + gap: '0.625rem', + flex: '1' +})); + export const ContentDetailsText = styled(Typography)(({ theme }) => ({ fontFamily: 'inherit', fontSize: '1rem', From b30a3245e9a3b362bf54b515abe3b7a4cff8cdc5 Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Mon, 4 Nov 2024 07:20:48 +0530 Subject: [PATCH 07/66] fix(check): add missing props Signed-off-by: Sudhanshu Dasgupta --- src/custom/CatalogDetail/ActionButton.tsx | 26 +++++++++-------------- src/custom/CatalogDetail/LeftPanel.tsx | 6 ++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/custom/CatalogDetail/ActionButton.tsx b/src/custom/CatalogDetail/ActionButton.tsx index 8d000e1d..1cd4ff66 100644 --- a/src/custom/CatalogDetail/ActionButton.tsx +++ b/src/custom/CatalogDetail/ActionButton.tsx @@ -17,7 +17,7 @@ interface ActionButtonsProps { isCloneLoading: boolean; handleClone: (name: string, id: string) => void; mode: string; - handleUnpublish?: () => void; + handleUnpublish: () => void; isCloneDisabled: boolean; showOpenPlaygroundButton: boolean; showUnpublishAction: boolean; @@ -117,23 +117,17 @@ const ActionButtons: React.FC = ({ )} {showUnpublishAction && ( - - - - Unpublish - - + + Unpublish + )} ); diff --git a/src/custom/CatalogDetail/LeftPanel.tsx b/src/custom/CatalogDetail/LeftPanel.tsx index 30d00607..70ed50d2 100644 --- a/src/custom/CatalogDetail/LeftPanel.tsx +++ b/src/custom/CatalogDetail/LeftPanel.tsx @@ -22,6 +22,8 @@ interface LeftPanelProps { technologySVGSubpath: string; fontFamily?: string; showOpenPlaygroundButton?: boolean; + handleUnpublish: () => void; + showUnpublishAction?: boolean; } const LeftPanel: React.FC = ({ @@ -31,6 +33,7 @@ const LeftPanel: React.FC = ({ actionItems = true, isCloneLoading, handleClone, + handleUnpublish, showTechnologies = true, mode, filteredAcademyData, @@ -38,6 +41,7 @@ const LeftPanel: React.FC = ({ technologySVGPath, technologySVGSubpath, fontFamily, + showUnpublishAction = false, showOpenPlaygroundButton = true }) => { const theme = useTheme(); @@ -77,6 +81,8 @@ const LeftPanel: React.FC = ({ cardId={cardId} isCloneLoading={isCloneLoading} handleClone={handleClone} + showUnpublishAction={showUnpublishAction} + handleUnpublish={handleUnpublish} mode={mode} isCloneDisabled={isCloneDisabled} showOpenPlaygroundButton={showOpenPlaygroundButton} From 1f4fce9bbb79b514f3394daff2c11adf0f5dcc9b Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Mon, 4 Nov 2024 10:25:22 +0530 Subject: [PATCH 08/66] fix(style): add border Signed-off-by: Sudhanshu Dasgupta --- src/custom/CatalogDetail/style.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom/CatalogDetail/style.tsx b/src/custom/CatalogDetail/style.tsx index 81867492..672137aa 100644 --- a/src/custom/CatalogDetail/style.tsx +++ b/src/custom/CatalogDetail/style.tsx @@ -48,7 +48,7 @@ export const UnpublishAction = styled('div')(({ disabled = fa alignItems: 'center', borderRadius: '0.5rem', backgroundColor: 'transparent', - border: theme.palette.border.default, + border: `1px solid ${theme.palette.border.normal}`, padding: '0.5rem', color: theme.palette.text.default, gap: '0.625rem', From a07edba3ac757853603a3217e4436fbc82efc656 Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Mon, 4 Nov 2024 16:56:16 +0530 Subject: [PATCH 09/66] fix(error): rm unwanted and add version Signed-off-by: Sudhanshu Dasgupta --- src/custom/ErrorBoundary/ErrorBoundary.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/custom/ErrorBoundary/ErrorBoundary.tsx b/src/custom/ErrorBoundary/ErrorBoundary.tsx index 6858e896..a47c3e8c 100644 --- a/src/custom/ErrorBoundary/ErrorBoundary.tsx +++ b/src/custom/ErrorBoundary/ErrorBoundary.tsx @@ -34,11 +34,16 @@ interface FallbackComponentProps extends FallbackProps { children?: React.ReactNode; pageUrl?: string; timestamp?: string; + showPackageInfo?: boolean; + version?: string; } -export function Fallback({ error, children }: FallbackComponentProps): JSX.Element { - const pageUrl = window.location.href; - const timestamp = new Date().toLocaleString(); +export function Fallback({ + error, + children, + showPackageInfo, + version +}: FallbackComponentProps): JSX.Element { return (

Uh-oh!😔 Please pardon the mesh.

@@ -48,9 +53,11 @@ export function Fallback({ error, children }: FallbackComponentProps): JSX.Eleme {(error as Error).message}
- URL: {pageUrl} -
- Logged at: {timestamp} + {showPackageInfo && ( + <> + Version: {version} + + )} We apologize for the inconvenience. The issue may be on our end. If troubleshooting doesn't From 19f56f194f869a4a02e2f6943ef5a794e666d52c Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Tue, 5 Nov 2024 12:38:51 +0530 Subject: [PATCH 10/66] feat: create user serach field component Signed-off-by: Amit Amrutiya --- .../UserSearchField/UserSearchFieldInput.tsx | 325 ++++++++++++++++++ src/custom/UserSearchField/index.ts | 3 + 2 files changed, 328 insertions(+) create mode 100644 src/custom/UserSearchField/UserSearchFieldInput.tsx create mode 100644 src/custom/UserSearchField/index.ts diff --git a/src/custom/UserSearchField/UserSearchFieldInput.tsx b/src/custom/UserSearchField/UserSearchFieldInput.tsx new file mode 100644 index 00000000..cbced2b8 --- /dev/null +++ b/src/custom/UserSearchField/UserSearchFieldInput.tsx @@ -0,0 +1,325 @@ +import { Autocomplete, AutocompleteRenderInputParams } from '@mui/material'; +import { debounce } from 'lodash'; +import React, { SyntheticEvent, useMemo, useState } from 'react'; +import { + Avatar, + Box, + Checkbox, + Chip, + CircularProgress, + FormControlLabel, + FormGroup, + Grid, + TextField, + Tooltip, + Typography +} from '../../base'; +import { iconSmall } from '../../constants/iconsSizes'; +import { CloseIcon, PersonIcon } from '../../icons'; + +interface User { + user_id: string; + first_name: string; + last_name: string; + email: string; + avatar_url?: string; + deleted_at?: { Valid: boolean }; + deleted?: boolean; +} + +interface UserSearchFieldProps { + usersData: User[]; + setUsersData: React.Dispatch>; + label?: string; + setDisableSave?: (disable: boolean) => void; + handleNotifyPref?: () => void; + notifyUpdate?: boolean; + isCreate?: boolean; + searchType?: string; + disabled?: boolean; + org_id?: string; + currentUserData: User; + searchedUsers: User[]; + isUserSearchLoading: boolean; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + fetchSearchedUsers: any; + usersSearch: string; + setUsersSearch: React.Dispatch>; +} + +const UserSearchField: React.FC = ({ + usersData, + setUsersData, + label, + setDisableSave, + handleNotifyPref, + notifyUpdate, + isCreate, + searchType, + disabled = false, + currentUserData, + searchedUsers, + isUserSearchLoading, + fetchSearchedUsers, + usersSearch, + setUsersSearch +}) => { + const [error, setError] = useState(''); + const [inputValue, setInputValue] = useState(''); + const [open, setOpen] = useState(false); + const [showAllUsers, setShowAllUsers] = useState(false); + const [hasInitialFocus, setHasInitialFocus] = useState(true); + // Combine current user with search results + const displayOptions = useMemo(() => { + if (!searchedUsers) return []; + + // Filter out current user from search results + const filteredResults = searchedUsers.filter( + (user: User) => user.user_id !== currentUserData?.user_id + ); + // Show only current user on initial focus + if (hasInitialFocus && !usersSearch && currentUserData) { + return [currentUserData]; + } + // If there's no search query, add current user at the top + if (!usersSearch && currentUserData) { + return [currentUserData, ...filteredResults]; + } + return filteredResults; + }, [searchedUsers, currentUserData, usersSearch, hasInitialFocus]); + + const fetchSuggestions = debounce((value: string) => { + setHasInitialFocus(false); + setUsersSearch(value); + fetchSearchedUsers(); + }, 300); + + const handleDelete = (email: string) => { + const usersDataSet = new Set(usersData); + usersDataSet.forEach((avatarObj: User) => { + if (avatarObj.email === email) { + usersDataSet.delete(avatarObj); + } + }); + setUsersData(Array.from(usersDataSet)); + if (setDisableSave) { + setDisableSave(false); + } + }; + + const handleAdd = (event: SyntheticEvent, value: User) => { + if (!value) return; + + setUsersData((prevData: User[]) => { + prevData = prevData || []; + const isDuplicate = prevData?.some((user) => user.user_id === value.user_id); + const isDeleted = value.deleted_at?.Valid === true; + + if (isDuplicate || isDeleted) { + setError(isDuplicate ? 'User already selected' : 'User does not exist'); + return prevData; + } + + setError(''); + return [...prevData, value]; + }); + + // Reset UI state after updating users + setInputValue(''); + setOpen(false); + setUsersSearch(''); + + if (setDisableSave) { + setDisableSave(false); + } + }; + + const handleInputChange = (event: SyntheticEvent, value: string) => { + if (value === '') { + setOpen(true); + setUsersSearch(''); + setHasInitialFocus(true); + } else { + const encodedValue = encodeURIComponent(value); + fetchSuggestions(encodedValue); + setError(''); + setOpen(true); + } + }; + + const handleFocus = () => { + setOpen(true); + if (!usersSearch) { + setHasInitialFocus(true); + } + }; + + const handleBlur = () => { + setOpen(false); + setUsersSearch(''); + // Reset initial focus state when field is blurred + setHasInitialFocus(true); + }; + + return ( + <> + x} + options={displayOptions} + disableClearable + includeInputInList + filterSelectedOptions + disableListWrap + disabled={disabled} + open={open} + loading={isUserSearchLoading} + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + value={inputValue} + getOptionLabel={() => ''} + noOptionsText={isUserSearchLoading ? 'Loading...' : 'No users found'} + onChange={handleAdd} + onInputChange={handleInputChange} + isOptionEqualToValue={(option: User, value: User) => option.user_id === value.user_id} + clearOnBlur + onFocus={handleFocus} + onBlur={handleBlur} + renderInput={(params: AutocompleteRenderInputParams) => ( + + {isUserSearchLoading ? : null} + + ) + }} + /> + )} + renderOption={(props, option: User) => ( +
  • + + + + + {option.avatar_url ? '' : } + + + + + {option.deleted ? ( + + {option.email} (deleted) + + ) : ( + <> + + {option.first_name} {option.last_name} + + + {option.email} + + + )} + + +
  • + )} + /> + + {/* TODO: Remove dependancy of this checkbox in this component, it should be defined on parent component. We should keep this component reusable and should not add checkbox specific to some component */} + {!isCreate && ( + +
    + + } + label={`Notify ${searchType} of membership change`} + /> +
    +
    + )} + 0 ? '0.5rem' : '' + }} + > + {!showAllUsers && usersData?.length > 0 && ( + + {usersData[usersData.length - 1]?.avatar_url + ? '' + : usersData[usersData.length - 1]?.first_name?.charAt(0)} + + } + label={usersData[usersData.length - 1]?.email} + size="small" + onDelete={() => handleDelete(usersData[usersData.length - 1]?.email)} + deleteIcon={ + + + + } + /> + )} + {showAllUsers && + usersData?.map((avatarObj: User) => ( + + {avatarObj.avatar_url ? '' : avatarObj.first_name?.charAt(0)} + + } + label={avatarObj.email} + size="small" + onDelete={() => handleDelete(avatarObj.email)} + deleteIcon={ + + + + } + /> + ))} + {usersData?.length > 1 && ( + setShowAllUsers(!showAllUsers)} + sx={{ + cursor: 'pointer', + color: 'white', + fontWeight: '600', + '&:hover': { + color: 'black' + } + }} + > + {showAllUsers ? '(hide)' : `(+${usersData.length - 1})`} + + )} + + + ); +}; + +export default UserSearchField; diff --git a/src/custom/UserSearchField/index.ts b/src/custom/UserSearchField/index.ts new file mode 100644 index 00000000..7cf9a5ea --- /dev/null +++ b/src/custom/UserSearchField/index.ts @@ -0,0 +1,3 @@ +import UserSearchField from './UserSearchFieldInput'; + +export { UserSearchField }; From 42783be2869ba86d9650637faa2580f6f20d0bdb Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Tue, 5 Nov 2024 12:39:22 +0530 Subject: [PATCH 11/66] feat: add InputFieldSearch component for user search functionality Signed-off-by: Amit Amrutiya --- .../InputSearchField/InputSearchField.tsx | 189 ++++++++++++++++++ src/custom/InputSearchField/index.ts | 3 + src/custom/index.tsx | 2 + 3 files changed, 194 insertions(+) create mode 100644 src/custom/InputSearchField/InputSearchField.tsx create mode 100644 src/custom/InputSearchField/index.ts diff --git a/src/custom/InputSearchField/InputSearchField.tsx b/src/custom/InputSearchField/InputSearchField.tsx new file mode 100644 index 00000000..80d1b510 --- /dev/null +++ b/src/custom/InputSearchField/InputSearchField.tsx @@ -0,0 +1,189 @@ +import { Autocomplete } from '@mui/material'; +import React, { useEffect, useRef, useState } from 'react'; +import { Box, Chip, Grid, TextField, Tooltip, Typography } from '../../base'; +import { iconLarge, iconSmall } from '../../constants/iconsSizes'; +import { CloseIcon, OrgIcon } from '../../icons'; + +interface Option { + id: string; + name: string; +} + +interface InputFieldSearchProps { + defaultData?: Option[]; + label?: string; + fetchSuggestions: (value: string) => void; + setFilterData: (data: Option[]) => void; + isLoading: boolean; + type: string; + disabled?: boolean; +} + +const InputFieldSearch: React.FC = ({ + defaultData = [], + label, + fetchSuggestions, + setFilterData, + isLoading, + type, + disabled +}) => { + const [data, setData] = useState([]); + const [error, setError] = useState(''); + const [inputValue, setInputValue] = useState(''); + const [open, setOpen] = useState(false); + const [showAllUsers, setShowAllUsers] = useState(false); + const [selectedOption, setSelectedOption] = useState
    ) - }, - { - title: 'Open in playground', - onClick: () => handleOpenPlayground(rowData.id, rowData.name), - icon: } ]; + // Conditionally add playground and unpublish buttons + const actionsList = [...baseActions]; - const actionsList = showUnpublish - ? [ - ...baseActions.slice(0, 2), - { - title: 'Unpublish', - onClick: () => handleUnpublish(rowData), - disabled: isUnpublishDisabled, - icon: - }, - ...baseActions.slice(2) - ] - : baseActions; + if (showUnpublish) { + actionsList.splice(2, 0, { + title: 'Unpublish', + onClick: () => handleUnpublish(rowData), + disabled: isUnpublishDisabled, + icon: + }); + } + if (showOpenPlayground) { + actionsList.splice(2, 0, { + title: 'Open in playground', + onClick: () => handleOpenPlayground(rowData.id, rowData.name), + icon: + }); + } //@ts-ignore return ; } From 2c8c92aa8edac7ec7ce51c43347137ca16c5668c Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Wed, 13 Nov 2024 20:10:22 +0530 Subject: [PATCH 45/66] fix: update links to point to cloud.layer5.io Signed-off-by: Amit Amrutiya --- src/custom/CatalogDetail/ChallengesSection.tsx | 4 ++-- src/custom/CatalogDetail/LearningSection.tsx | 4 ++-- src/custom/CatalogDetail/UserInfo.tsx | 4 ++-- src/custom/CatalogDetail/helper.ts | 2 ++ 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/custom/CatalogDetail/ChallengesSection.tsx b/src/custom/CatalogDetail/ChallengesSection.tsx index 77028a2f..67207bd6 100644 --- a/src/custom/CatalogDetail/ChallengesSection.tsx +++ b/src/custom/CatalogDetail/ChallengesSection.tsx @@ -3,7 +3,7 @@ import { Link, ListItemIcon } from '../../base'; import { ChallengesIcon } from '../../icons'; import { useTheme } from '../../theme'; import CollapsibleSection from './CollapsibleSection'; -import { slugify } from './helper'; +import { CLOUD_URL, slugify } from './helper'; import { LabelDiv } from './style'; import { FilteredAcademyData } from './types'; @@ -29,7 +29,7 @@ const ChallengesSection: React.FC = ({ filteredAcademyDa const renderChallengeItem = (item: string, index: number) => ( = ({ filteredAcademyData } const renderLearningItem = (item: string, index: number) => ( = ({ details, showVersion = true, userPr }} /> diff --git a/src/custom/CatalogDetail/helper.ts b/src/custom/CatalogDetail/helper.ts index 2d6601f7..7237f1aa 100644 --- a/src/custom/CatalogDetail/helper.ts +++ b/src/custom/CatalogDetail/helper.ts @@ -1,5 +1,7 @@ import jsyaml from 'js-yaml'; +export const CLOUD_URL = 'https://cloud.layer5.io'; + export const downloadYaml = (filteredData: string, itemName: string): void => { const yamlData = Array.isArray(filteredData) ? jsyaml.dump(filteredData.find((item) => item.name === itemName)) From 15eb7be562d053c43ea7ba93fd2e0b63cdfe1c33 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Wed, 13 Nov 2024 20:15:40 +0530 Subject: [PATCH 46/66] feat: update path Signed-off-by: Amit Amrutiya --- src/constants/constants.ts | 1 + src/custom/CatalogDetail/ChallengesSection.tsx | 3 ++- src/custom/CatalogDetail/LearningSection.tsx | 3 ++- src/custom/CatalogDetail/UserInfo.tsx | 3 ++- src/custom/CatalogDetail/helper.ts | 2 -- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 3b23acd7..e65be201 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -6,3 +6,4 @@ export const KEPPEL_GREEN_FILL = '#00B39F'; 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'; diff --git a/src/custom/CatalogDetail/ChallengesSection.tsx b/src/custom/CatalogDetail/ChallengesSection.tsx index 67207bd6..2cec1cd7 100644 --- a/src/custom/CatalogDetail/ChallengesSection.tsx +++ b/src/custom/CatalogDetail/ChallengesSection.tsx @@ -1,9 +1,10 @@ import { useEffect, useState } from 'react'; import { Link, ListItemIcon } from '../../base'; +import { CLOUD_URL } from '../../constants/constants'; import { ChallengesIcon } from '../../icons'; import { useTheme } from '../../theme'; import CollapsibleSection from './CollapsibleSection'; -import { CLOUD_URL, slugify } from './helper'; +import { slugify } from './helper'; import { LabelDiv } from './style'; import { FilteredAcademyData } from './types'; diff --git a/src/custom/CatalogDetail/LearningSection.tsx b/src/custom/CatalogDetail/LearningSection.tsx index af9a62a8..4af9f852 100644 --- a/src/custom/CatalogDetail/LearningSection.tsx +++ b/src/custom/CatalogDetail/LearningSection.tsx @@ -1,9 +1,10 @@ import React, { useEffect, useState } from 'react'; import { Link, ListItemIcon } from '../../base'; +import { CLOUD_URL } from '../../constants/constants'; import { LearningIcon } from '../../icons'; import { useTheme } from '../../theme'; import CollapsibleSection from './CollapsibleSection'; -import { CLOUD_URL, slugify } from './helper'; +import { slugify } from './helper'; import { LabelDiv } from './style'; import { FilteredAcademyData } from './types'; diff --git a/src/custom/CatalogDetail/UserInfo.tsx b/src/custom/CatalogDetail/UserInfo.tsx index 124d801c..8a55ffa2 100644 --- a/src/custom/CatalogDetail/UserInfo.tsx +++ b/src/custom/CatalogDetail/UserInfo.tsx @@ -1,7 +1,8 @@ import { Avatar } from '../../base'; +import { CLOUD_URL } from '../../constants/constants'; import { Pattern } from '../CustomCatalog/CustomCard'; import { getVersion } from '../CustomCatalog/Helper'; -import { CLOUD_URL, formatDate } from './helper'; +import { formatDate } from './helper'; import { ContentDetailsPoints, ContentDetailsText, ContentRow, RedirectLink } from './style'; import { UserProfile } from './types'; diff --git a/src/custom/CatalogDetail/helper.ts b/src/custom/CatalogDetail/helper.ts index 7237f1aa..2d6601f7 100644 --- a/src/custom/CatalogDetail/helper.ts +++ b/src/custom/CatalogDetail/helper.ts @@ -1,7 +1,5 @@ import jsyaml from 'js-yaml'; -export const CLOUD_URL = 'https://cloud.layer5.io'; - export const downloadYaml = (filteredData: string, itemName: string): void => { const yamlData = Array.isArray(filteredData) ? jsyaml.dump(filteredData.find((item) => item.name === itemName)) From e65bd46edd9a6c1d82760b5c67612cea2da93c93 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Thu, 14 Nov 2024 14:47:17 +0530 Subject: [PATCH 47/66] feat: update user profile link to open in a new tab using CLOUD_URL Signed-off-by: Amit Amrutiya --- src/custom/CatalogDesignTable/columnConfig.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/custom/CatalogDesignTable/columnConfig.tsx b/src/custom/CatalogDesignTable/columnConfig.tsx index b56e37f2..84416a36 100644 --- a/src/custom/CatalogDesignTable/columnConfig.tsx +++ b/src/custom/CatalogDesignTable/columnConfig.tsx @@ -3,6 +3,7 @@ import { MUIDataTableColumn, MUIDataTableMeta } from 'mui-datatables'; import { FacebookShareButton, LinkedinShareButton, TwitterShareButton } from 'react-share'; import { Avatar, Box, Grid, Typography } from '../../base'; +import { CLOUD_URL } from '../../constants/constants'; import { iconMedium } from '../../constants/iconsSizes'; import { ChainIcon, @@ -165,7 +166,7 @@ export const createDesignColumns = ({ alt={displayName} src={avatar_url} onClick={() => { - window.location.href = `/user/${user_id}`; + window.open(`${CLOUD_URL}/user/${user_id}`, '_blank'); }} > {!avatar_url && } From 0295e0493f641895cb1c00f6077ad69d971f15ff Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Thu, 14 Nov 2024 14:47:36 +0530 Subject: [PATCH 48/66] feat: wrap IconButton in a div for improved styling and structure Signed-off-by: Amit Amrutiya --- src/custom/TooltipIcon.tsx | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/custom/TooltipIcon.tsx b/src/custom/TooltipIcon.tsx index 87477e8b..86cc6325 100644 --- a/src/custom/TooltipIcon.tsx +++ b/src/custom/TooltipIcon.tsx @@ -20,21 +20,23 @@ export function TooltipIcon({ }: TooltipIconProps): JSX.Element { return ( - + - {icon} - + ...(style as SxProps) + }} + disableRipple + > + {icon} + +
    ); } From dba20bed9d037f6c618c8d1de1efcfb33e0da10f Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Thu, 14 Nov 2024 15:04:44 +0530 Subject: [PATCH 49/66] feat: update MUIDataTable styling to include width adjustment for better responsiveness Signed-off-by: Amit Amrutiya --- src/custom/ResponsiveDataTable.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index aa1c51aa..a133ae7f 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -122,11 +122,12 @@ export const DataTableEllipsisMenu: React.FC<{ const dataTableTheme = (theme: Theme, backgroundColor?: string) => createTheme({ components: { - MUIDataTable: { + MuiPaper: { styleOverrides: { - paper: { + root: { background: backgroundColor || theme.palette.background.default, - maxWidth: '-moz-available' + maxWidth: '-moz-available', + width: '-moz-available' } } }, From d97abce1183fa8b4db16377b96de230c6e6f4bc4 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Thu, 14 Nov 2024 21:21:33 +0530 Subject: [PATCH 50/66] feat: add data dependency to updateColumnsEffect for improved responsiveness Signed-off-by: Amit Amrutiya --- src/custom/ResponsiveDataTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index a133ae7f..7f99704f 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -387,7 +387,7 @@ const ResponsiveDataTable = ({ }); updateCols && updateCols([...columns]); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [columnVisibility, updateCols]); + }, [columnVisibility, updateCols, data]); React.useEffect(() => { updateColumnsEffect(); From cd42bca8fa123ef0e3f616daef77256e28f49be5 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Fri, 15 Nov 2024 15:20:20 +0530 Subject: [PATCH 51/66] feat: remove width property from dataTableTheme for cleaner styling Signed-off-by: Amit Amrutiya --- src/custom/ResponsiveDataTable.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index 7f99704f..55098698 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -126,8 +126,7 @@ const dataTableTheme = (theme: Theme, backgroundColor?: string) => styleOverrides: { root: { background: backgroundColor || theme.palette.background.default, - maxWidth: '-moz-available', - width: '-moz-available' + maxWidth: '-moz-available' } } }, From d98f75b70875f76c466b05875f48d5318c1634db Mon Sep 17 00:00:00 2001 From: jerensl <54782057+jerensl@users.noreply.github.com> Date: Sun, 17 Nov 2024 11:47:34 +0800 Subject: [PATCH 52/66] chore: udpate title auto pr sistent Signed-off-by: jerensl <54782057+jerensl@users.noreply.github.com> --- .github/workflows/bump-meshery-version.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/bump-meshery-version.yml b/.github/workflows/bump-meshery-version.yml index f82332b4..d38b5540 100644 --- a/.github/workflows/bump-meshery-version.yml +++ b/.github/workflows/bump-meshery-version.yml @@ -51,7 +51,7 @@ jobs: signoff: true branch: bump-sistent-bot delete-branch: true - title: '[Chore]: Bump v${{ needs.versions-check.outputs.current }}' + title: '[Chore]: Bump Sistent v${{ needs.versions-check.outputs.current }}' add-paths: | ui/package.json ui/package-lock.json @@ -90,7 +90,7 @@ jobs: signoff: true branch: bump-sistent-bot delete-branch: true - title: '[Chore]: Bump v${{needs.versions-check.outputs.current }}' + title: '[Chore]: Bump Sistent v${{needs.versions-check.outputs.current }}' add-paths: | meshmap/package.json meshmap/package-lock.json @@ -129,7 +129,7 @@ jobs: signoff: true branch: bump-sistent-bot delete-branch: true - title: '[Chore]: Bump v${{ needs.versions-check.outputs.current }}' + title: '[Chore]: Bump Sistent v${{ needs.versions-check.outputs.current }}' add-paths: | ui/package.json ui/package-lock.json From aed7a694dd2122cb0476991b79138fc9b4715e72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Nov 2024 03:50:00 +0000 Subject: [PATCH 53/66] chore(deps): bump cross-spawn and gatsby-cli in /site Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) and [gatsby-cli](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-cli). These dependencies needed to be updated together. Updates `cross-spawn` from 7.0.3 to 7.0.5 - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.5) Updates `gatsby-cli` from 5.12.4 to 5.14.0 - [Release notes](https://github.com/gatsbyjs/gatsby/releases) - [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-cli/CHANGELOG.md) - [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-cli@5.14.0/packages/gatsby-cli) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect - dependency-name: gatsby-cli dependency-type: indirect ... Signed-off-by: dependabot[bot] --- site/package-lock.json | 334 +++++++++++++++++++++++------------------ 1 file changed, 191 insertions(+), 143 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 22b8c8fe..efbf0241 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -4798,25 +4798,6 @@ "resolved": "https://registry.npmjs.org/application-config-path/-/application-config-path-0.1.1.tgz", "integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==" }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -5901,124 +5882,157 @@ } }, "node_modules/clipboardy": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", - "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-4.0.0.tgz", + "integrity": "sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==", "dependencies": { - "arch": "^2.1.1", - "execa": "^1.0.0", - "is-wsl": "^2.1.1" + "execa": "^8.0.1", + "is-wsl": "^3.1.0", + "is64bit": "^2.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/clipboardy/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "node": ">=18" }, - "engines": { - "node": ">=4.8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/clipboardy/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/clipboardy/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dependencies": { - "pump": "^3.0.0" + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "engines": { + "node": ">=16" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "engines": { - "node": ">=6" + "node": ">=16.17.0" } }, "node_modules/clipboardy/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "engines": { - "node": ">=0.10.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clipboardy/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "node_modules/clipboardy/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dependencies": { - "path-key": "^2.0.0" + "is-inside-container": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clipboardy/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "node_modules/clipboardy/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clipboardy/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" + "node_modules/clipboardy/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clipboardy/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "node_modules/clipboardy/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dependencies": { - "shebang-regex": "^1.0.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clipboardy/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "node_modules/clipboardy/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clipboardy/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" + "node_modules/clipboardy/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" }, - "bin": { - "which": "bin/which" + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/clipboardy/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cliui": { @@ -6388,9 +6402,9 @@ } }, "node_modules/create-gatsby": { - "version": "3.12.3", - "resolved": "https://registry.npmjs.org/create-gatsby/-/create-gatsby-3.12.3.tgz", - "integrity": "sha512-N0K/Z/MD5LMRJcBy669WpSgrn+31zBV72Lv0RHolX0fXa77Yx58HsEiLWz83j/dtciGMQfEOEHFRetUqZhOggA==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/create-gatsby/-/create-gatsby-3.14.0.tgz", + "integrity": "sha512-HR90NlcTIAeo7OwcFfGubKa35+/Aj7lEfgcV4n4IIPCMy3A+gYwOEQcLIGtmPCVIl1C9AhT3/0XaWbnhAcbyGQ==", "dependencies": { "@babel/runtime": "^7.20.13" }, @@ -6407,9 +6421,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -8690,9 +8704,9 @@ "integrity": "sha512-kSxoARUDn4F2RPXX48UXnaFKwVU7Ivd/6qpzZL29MCDmr9sTvybv4gFCp+qaI4fM9m0z9fgz/yJvi56GAz+BZg==" }, "node_modules/fs-extra": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", - "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -8951,9 +8965,9 @@ } }, "node_modules/gatsby-cli": { - "version": "5.12.4", - "resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-5.12.4.tgz", - "integrity": "sha512-GD+otyd5LlgSbYK4ODrKyAise/k32G7Qy7H/k+gJ2P8DCG9sU+j//2zNwF7mY8C5dl0SpROqFTL+I0Y1DK4tmQ==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-5.14.0.tgz", + "integrity": "sha512-NvsWsuZdpNRStmDsNZaYveifFrFqFNy4rnFCLAWWghyxUks8qhGwy6wrz2kcUK+Y2sRJJn1eIjgwzi1AyFn5fQ==", "hasInstallScript": true, "dependencies": { "@babel/code-frame": "^7.18.6", @@ -8969,16 +8983,15 @@ "better-opn": "^2.1.1", "boxen": "^5.1.2", "chalk": "^4.1.2", - "clipboardy": "^2.3.0", + "clipboardy": "^4.0.0", "common-tags": "^1.8.2", "convert-hrtime": "^3.0.0", - "create-gatsby": "^3.12.3", + "create-gatsby": "^3.14.0", "envinfo": "^7.10.0", "execa": "^5.1.1", "fs-exists-cached": "^1.0.0", - "fs-extra": "^11.1.1", - "gatsby-core-utils": "^4.12.1", - "gatsby-telemetry": "^4.12.1", + "fs-extra": "^11.2.0", + "gatsby-core-utils": "^4.14.0", "hosted-git-info": "^3.0.8", "is-valid-path": "^0.1.1", "joi": "^17.9.2", @@ -9006,18 +9019,18 @@ } }, "node_modules/gatsby-core-utils": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-4.12.1.tgz", - "integrity": "sha512-YW7eCK2M6yGQerT5LkdOHLZTNYMsDvcgeDMRy0q66FWKj7twPZX428I6NaLCMeF5dYoj1HOOO0u96iNlW5jcKQ==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-4.14.0.tgz", + "integrity": "sha512-h0v20gB213PmhKjioCJ93SrUb7Hihnqxd6X6Iur4u1eiWTUDsGeV9g1bkquiuDl2qovUnjj7mOoHdWiu/Ax/9Q==", "dependencies": { "@babel/runtime": "^7.20.13", "ci-info": "2.0.0", "configstore": "^5.0.1", "fastq": "^1.15.0", "file-type": "^16.5.4", - "fs-extra": "^11.1.1", + "fs-extra": "^11.2.0", "got": "^11.8.6", - "hash-wasm": "^4.9.0", + "hash-wasm": "^4.11.0", "import-from": "^4.0.0", "lmdb": "2.5.3", "lock": "^1.1.0", @@ -9915,9 +9928,9 @@ } }, "node_modules/hash-wasm": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.10.0.tgz", - "integrity": "sha512-a0NjBNWjavvMalm/pPSEJ00MPDjRG8rv9D5BK7dBQTLGwAOVWqnTEUggaYs5szATB5UK5ULeIQr7QJXbczAZYA==" + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.11.0.tgz", + "integrity": "sha512-HVusNXlVqHe0fzIzdQOGolnFN6mX/fqcrSAOcTBXdvzrXVHwTz11vXeKRmkR5gTuwVpvHZEIyKoePDvuAR+XwQ==" }, "node_modules/hasha": { "version": "5.2.2", @@ -10456,6 +10469,37 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-invalid-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", @@ -10777,6 +10821,20 @@ "node": ">=8" } }, + "node_modules/is64bit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is64bit/-/is64bit-2.0.0.tgz", + "integrity": "sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==", + "dependencies": { + "system-architecture": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -11615,11 +11673,6 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -12000,14 +12053,6 @@ "node": ">=8" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -14775,14 +14820,6 @@ "node": ">=4" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -14963,6 +15000,17 @@ "tslib": "^2.0.3" } }, + "node_modules/system-architecture": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/system-architecture/-/system-architecture-0.1.0.tgz", + "integrity": "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", From db0bc61b86704435ebbd4263264bb66b06464d69 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:01:05 +0530 Subject: [PATCH 54/66] refactor: optimize updatedOptions with useMemo for performance Signed-off-by: Amit Amrutiya --- src/custom/ResponsiveDataTable.tsx | 62 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index 55098698..230822db 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -307,42 +307,45 @@ const ResponsiveDataTable = ({ year: 'numeric' }; - return new Intl.DateTimeFormat('un-US', dateOptions).format(date); + return new Intl.DateTimeFormat('en-US', dateOptions).format(date); }; - const updatedOptions = { - ...options, - print: false, - download: false, - search: false, - filter: false, - viewColumns: false, - rowsPerPageOptions: rowsPerPageOptions, - onViewColumnsChange: (column: string, action: string) => { - switch (action) { - case 'add': { - const colToAdd = columns.find((obj) => obj.name === column); - if (colToAdd) { - if (colToAdd.options) { - colToAdd.options.display = true; - updateCols && updateCols([...columns]); + const updatedOptions = React.useMemo( + () => ({ + ...options, + print: false, + download: false, + search: false, + filter: false, + viewColumns: false, + rowsPerPageOptions: rowsPerPageOptions, + onViewColumnsChange: (column: string, action: string) => { + switch (action) { + case 'add': { + const colToAdd = columns.find((obj) => obj.name === column); + if (colToAdd) { + if (colToAdd.options) { + colToAdd.options.display = true; + updateCols && updateCols([...columns]); + } } + break; } - break; - } - case 'remove': { - const colToRemove = columns.find((obj) => obj.name === column); - if (colToRemove) { - if (colToRemove.options) { - colToRemove.options.display = false; - updateCols && updateCols([...columns]); + case 'remove': { + const colToRemove = columns.find((obj) => obj.name === column); + if (colToRemove) { + if (colToRemove.options) { + colToRemove.options.display = false; + updateCols && updateCols([...columns]); + } } + break; } - break; } } - } - }; + }), + [options, rowsPerPageOptions, columns, updateCols] + ); const updateColumnsEffect = useCallback(() => { columns?.forEach((col) => { @@ -385,8 +388,7 @@ const ResponsiveDataTable = ({ } }); updateCols && updateCols([...columns]); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [columnVisibility, updateCols, data]); + }, [columnVisibility, updateCols, columns]); React.useEffect(() => { updateColumnsEffect(); From b5f0f955b85626a4c447f0fbb40d6efc37af45d2 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:01:42 +0530 Subject: [PATCH 55/66] refactor: rename getBackground to getCatalogCardBackground for clarity Signed-off-by: Amit Amrutiya --- src/custom/CustomCatalog/style.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/custom/CustomCatalog/style.tsx b/src/custom/CustomCatalog/style.tsx index 38fb8005..4fa95643 100644 --- a/src/custom/CustomCatalog/style.tsx +++ b/src/custom/CustomCatalog/style.tsx @@ -348,15 +348,16 @@ export const CardBack = styled('div')(({ isCatalog }) => ({ }) })); -const getBackground = (isLightMode: boolean) => { +export const getCatalogCardBackground = (isLightMode: boolean) => { const lightGradient = `linear-gradient(to left bottom, ${WHITESMOKE}, ${GRAY97},white, white, white, white, white, white, white, white, ${WHITESMOKE}, ${GRAY97})`; const darkGradient = `linear-gradient(to right top, ${DARK_PRIMARY_COLOR}, ${accentGrey[30]}, ${accentGrey[20]}, ${accentGrey[10]}, ${accentGrey[10]}, ${accentGrey[10]}, ${accentGrey[10]}, ${accentGrey[10]}, ${accentGrey[10]}, ${charcoal[20]}, ${charcoal[10]}, black)`; return isLightMode ? lightGradient : darkGradient; }; + export const CardFront = styled('div')(({ shouldFlip, isDetailed, theme }) => { const isLightMode = theme.palette.mode === 'light'; - const background = getBackground(isLightMode); + const background = getCatalogCardBackground(isLightMode); const boxShadow = `2px 2px 3px 0px ${theme.palette.background.brand?.default}`; return { @@ -414,7 +415,7 @@ export const DesignAuthorName = styled('div')(() => ({ export const CatalogEmptyStateDiv = styled('div')(({ theme }) => { const isLightMode = theme.palette.mode === 'light'; - const background = getBackground(isLightMode); + const background = getCatalogCardBackground(isLightMode); const boxShadow = `2px 2px 3px 0px ${theme.palette.background.brand?.default}`; return { From df1613339f293c2bfe5b8fe8136732e9cc3aeb48 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:02:16 +0530 Subject: [PATCH 56/66] feat: add TrophyIcon component and export from icons index Signed-off-by: Amit Amrutiya --- src/icons/Tropy/TropyIcon.tsx | 28 ++++++++++++++++++++++++++++ src/icons/Tropy/index.ts | 1 + src/icons/index.ts | 1 + 3 files changed, 30 insertions(+) create mode 100644 src/icons/Tropy/TropyIcon.tsx create mode 100644 src/icons/Tropy/index.ts diff --git a/src/icons/Tropy/TropyIcon.tsx b/src/icons/Tropy/TropyIcon.tsx new file mode 100644 index 00000000..61c27069 --- /dev/null +++ b/src/icons/Tropy/TropyIcon.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +interface TrophyIconProps { + width?: string; + height?: string; + fill?: string; + style?: React.CSSProperties; +} + +const TrophyIcon: React.FC = ({ + width = '24', + height = '24', + fill = 'currentColor', + style = {} +}) => ( + + + +); + +export default TrophyIcon; diff --git a/src/icons/Tropy/index.ts b/src/icons/Tropy/index.ts new file mode 100644 index 00000000..7f82f5cc --- /dev/null +++ b/src/icons/Tropy/index.ts @@ -0,0 +1 @@ +export { default as TropyIcon } from './TropyIcon'; diff --git a/src/icons/index.ts b/src/icons/index.ts index 22a3a721..1f0b66b8 100644 --- a/src/icons/index.ts +++ b/src/icons/index.ts @@ -94,6 +94,7 @@ export * from './TerminalIcon'; export * from './Toolkit'; export * from './Touch'; export * from './Triangle'; +export * from './Tropy'; export * from './Undeploy'; export * from './Undo'; export * from './Validate'; From 1acf7004cb09dd3ad01677ca2d0c6189673c590d Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:02:57 +0530 Subject: [PATCH 57/66] feat: add PerformersSectionButton component with tooltip and skeleton loading Signed-off-by: Amit Amrutiya --- .../PerformersToogleButton.tsx | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/custom/PerformersSection/PerformersToogleButton.tsx diff --git a/src/custom/PerformersSection/PerformersToogleButton.tsx b/src/custom/PerformersSection/PerformersToogleButton.tsx new file mode 100644 index 00000000..a0555408 --- /dev/null +++ b/src/custom/PerformersSection/PerformersToogleButton.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { Button, Skeleton } from '../../base'; +import { TropyIcon } from '../../icons'; +import { useTheme } from '../../theme'; +import { CustomTooltip } from '../CustomTooltip'; +import { CardSkeleton } from './styles'; + +interface PerformersSectionButtonProps { + open: boolean; + handleClick: () => void; +} + +const PerformersSectionButton: React.FC = ({ open, handleClick }) => { + const theme = useTheme(); + + return ( + + + + + + ); +}; + +export const StateCardSekeleton = () => { + return ( + + {[...Array(5)].map((_, index) => ( + + ))} + + ); +}; +export default PerformersSectionButton; From dd6623b00ee477c755c5509d4279a453aea1adf3 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:03:22 +0530 Subject: [PATCH 58/66] feat: add PerformersSection component with metrics display and export Signed-off-by: Amit Amrutiya --- .../PerformersSection/PerformersSection.tsx | 316 ++++++++++++++++++ src/custom/PerformersSection/index.ts | 3 + src/custom/index.tsx | 1 + 3 files changed, 320 insertions(+) create mode 100644 src/custom/PerformersSection/PerformersSection.tsx create mode 100644 src/custom/PerformersSection/index.ts diff --git a/src/custom/PerformersSection/PerformersSection.tsx b/src/custom/PerformersSection/PerformersSection.tsx new file mode 100644 index 00000000..2fdcc1d8 --- /dev/null +++ b/src/custom/PerformersSection/PerformersSection.tsx @@ -0,0 +1,316 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { memo, useMemo } from 'react'; +import { + CloneIcon, + DeploymentsIcon, + DownloadIcon, + OpenIcon, + ShareIcon, + TropyIcon +} from '../../icons'; +import { useTheme } from '../../theme'; +import { Pattern } from '../CustomCatalog/CustomCard'; +import { ErrorBoundary } from '../ErrorBoundary'; +import { StateCardSekeleton } from './PerformersToogleButton'; +import { + CardsContainer, + ContentWrapper, + ErrorContainer, + HeaderSection, + HeaderTitle, + IconContainer, + MainContainer, + RepoSection, + RepoTitle, + StatsValue, + StatusLabel, + StyledCard, + Title, + UserNameText +} from './styles'; + +interface MetricConfig { + label: string; + icon: React.ComponentType; + id: string; + countKey: keyof Pattern; +} + +interface BaseQueryParams { + pathType: string; + page: number; + pagesize: number; + metrics: boolean; + expandUser: boolean; + trim: boolean; + order?: string; +} + +interface StatCardProps { + label: string; + count: number; + patternName: string; + pattern: Pattern; + userName: string; + userid: string; + icon: React.ComponentType; + status: string; + id: string; + onCardClick: (pattern: Pattern) => void; + onIconClick: () => void; + onAuthorClick: (userId: string) => void; + onStatusClick: (status: string) => void; +} + +interface PerformersSectionProps { + useGetCatalogFilters: (params: any) => any; + onCardClick: (pattern: Pattern) => void; + onIconClick: () => void; + onAuthorClick: (userId: string) => void; + onStatusClick: (status: string) => void; +} + +type MetricType = 'view' | 'clone' | 'download' | 'deployment' | 'share'; + +const BASE_QUERY_PARAMS: BaseQueryParams = { + pathType: 'pattern', + page: 0, + pagesize: 1, + metrics: true, + expandUser: true, + trim: true +}; + +const METRICS: Record = { + view: { + label: 'Most Opens', + icon: OpenIcon, + id: 'open-icon', + countKey: 'view_count' + }, + clone: { + label: 'Most Clones', + icon: CloneIcon, + id: 'clone-icon', + countKey: 'clone_count' + }, + download: { + label: 'Most Downloads', + icon: DownloadIcon, + id: 'download-icon', + countKey: 'download_count' + }, + deployment: { + label: 'Most Deploys', + icon: DeploymentsIcon, + id: 'deployments-icon', + countKey: 'deployment_count' + }, + share: { + label: 'Most Shares', + icon: ShareIcon, + id: 'share-icon', + countKey: 'share_count' + } +}; + +const createQueryParams = (metric: MetricType): BaseQueryParams => ({ + ...BASE_QUERY_PARAMS, + order: `${METRICS[metric].countKey} desc` +}); + +const StatCardComponent: React.FC = ({ + label, + count, + patternName, + pattern, + userName, + userid, + icon: Icon, + status, + id, + onCardClick, + onIconClick, + onAuthorClick, + onStatusClick +}) => { + const handleCardClick = () => { + onCardClick(pattern); + }; + + const handleIconClick = (e: React.MouseEvent) => { + e.stopPropagation(); + onIconClick(); + }; + + const handleAuthorClick = (e: React.MouseEvent) => { + e.stopPropagation(); + onAuthorClick(userid); + }; + + const handleStatusClick = (e: React.MouseEvent) => { + e.stopPropagation(); + onStatusClick(status); + }; + + return ( + + + + {label} + + + + + + {count} + + + {patternName} + by {userName} + + + + {status} + + + ); +}; +interface PageArgs { + search?: string; + order?: string; + pagesize?: number; + page?: number; + [key: string]: any; +} + +const withDefaultPageArgs = (args: PageArgs = {}): PageArgs => ({ + search: args.search ?? '', + order: args.order ?? '', + pagesize: args.pagesize ?? 0, + page: args.page ?? 0, + ...args +}); + +const StatCard = memo(StatCardComponent); +StatCard.displayName = 'StatCard'; + +const useMetricQueries = (useGetCatalogFilters: PerformersSectionProps['useGetCatalogFilters']) => { + const viewQuery = useGetCatalogFilters(withDefaultPageArgs(createQueryParams('view'))); + + const cloneQuery = useGetCatalogFilters(withDefaultPageArgs(createQueryParams('clone'))); + + const downloadQuery = useGetCatalogFilters(withDefaultPageArgs(createQueryParams('download'))); + + const deploymentQuery = useGetCatalogFilters( + withDefaultPageArgs(createQueryParams('deployment')) + ); + + const shareQuery = useGetCatalogFilters(withDefaultPageArgs(createQueryParams('share'))); + + const metricQueries = { + view: viewQuery, + clone: cloneQuery, + download: downloadQuery, + deployment: deploymentQuery, + share: shareQuery + }; + + return { + queries: metricQueries, + isLoading: Object.values(metricQueries).some((query) => query.isLoading), + hasError: Object.values(metricQueries).some((query) => query.isError) + }; +}; + +const processQueryData = ( + queries: Record, + metric: MetricType +): Omit< + StatCardProps, + 'onCardClick' | 'onIconClick' | 'onAuthorClick' | 'onStatusClick' +> | null => { + const query = queries[metric]; + const config = METRICS[metric]; + const pattern = query?.isSuccess && query.data?.patterns?.[0]; + + if (!pattern) return null; + + return { + label: config.label, + count: pattern[config.countKey], + patternName: pattern.name || 'Unknown', + pattern: pattern, + userName: pattern.user?.first_name || 'Unknown', + userid: pattern.user?.id, + icon: config.icon, + id: config.id, + status: pattern?.catalog_data?.content_class + }; +}; + +const PerformersSection: React.FC = ({ + useGetCatalogFilters, + onCardClick, + onIconClick, + onAuthorClick, + onStatusClick +}) => { + const theme = useTheme(); + const { queries, isLoading, hasError } = useMetricQueries(useGetCatalogFilters); + + const stats = useMemo( + () => + (Object.keys(METRICS) as MetricType[]) + .map((metric) => processQueryData(queries, metric)) + .filter( + ( + stat + ): stat is Omit< + StatCardProps, + 'onCardClick' | 'onIconClick' | 'onAuthorClick' | 'onStatusClick' + > => Boolean(stat) + ), + [queries] + ); + + if (hasError) + return ( + + Error loading statistics. Please try again later. + + ); + + return ( + + + + Top Performers + <TropyIcon + style={{ + height: '2rem', + width: '2rem', + color: theme.palette.icon.secondary + }} + /> + + + {isLoading && } + {!isLoading && + stats.map((stat, index) => ( + + ))} + + + + ); +}; + +export default memo(PerformersSection); diff --git a/src/custom/PerformersSection/index.ts b/src/custom/PerformersSection/index.ts new file mode 100644 index 00000000..1e6aa1ea --- /dev/null +++ b/src/custom/PerformersSection/index.ts @@ -0,0 +1,3 @@ +import PerformersSection from './PerformersSection'; +import PerformersSectionButton from './PerformersToogleButton'; +export { PerformersSection, PerformersSectionButton }; diff --git a/src/custom/index.tsx b/src/custom/index.tsx index 1918d175..ded1e4f5 100644 --- a/src/custom/index.tsx +++ b/src/custom/index.tsx @@ -51,6 +51,7 @@ export { InputSearchField } from './InputSearchField'; export { LearningContent } from './LearningContent'; export { NavigationNavbar } from './NavigationNavbar'; export { Note } from './Note'; +export { PerformersSection, PerformersSectionButton } from './PerformersSection'; export { SetupPreReq } from './SetupPrerequisite'; export { StyledChapter } from './StyledChapter'; export { StyledSearchBar } from './StyledSearchBar'; From 4fef955fdfb8bef12976aa2fff339691ab183a81 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:03:36 +0530 Subject: [PATCH 59/66] feat: add styles for PerformersSection component Signed-off-by: Amit Amrutiya --- src/custom/PerformersSection/styles.tsx | 261 ++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 src/custom/PerformersSection/styles.tsx diff --git a/src/custom/PerformersSection/styles.tsx b/src/custom/PerformersSection/styles.tsx new file mode 100644 index 00000000..365b7886 --- /dev/null +++ b/src/custom/PerformersSection/styles.tsx @@ -0,0 +1,261 @@ +import { Box, Card, CardContent, Typography } from '../../base'; +import { DARK_TEAL, styled } from '../../theme'; +import { getCatalogCardBackground } from '../CustomCatalog/style'; + +interface StatusLabelProps { + labelType?: 'community' | 'official' | string; +} + +interface ContentWrapperProps { + cardId?: string; +} + +interface StyledCardProps { + status?: string; +} + +export const ChartDiv = styled(Box)(() => ({ + padding: '1rem', + borderRadius: '1rem', + backgroundColor: 'white', + width: '100%', + alignSelf: 'center', + height: '20rem', + marginBottom: '1rem', + boxShadow: '0px 2px 10px rgba(0, 0, 0, 0.2)', + display: 'block', + ['@media (max-width:900px)']: { + height: '18rem', + marginInline: '0', + padding: '0.5rem' + } +})); + +export const LoadButtonDiv = styled('div')(() => ({ + width: '100%', + justifyContent: 'center', + display: 'flex', + alignItems: 'center', + marginTop: '20px' +})); + +export const EmptyContainer = styled(Box)(() => ({ + display: 'flex', + justifyContent: 'space-evenly', + gap: '2.5rem', + width: '100%' +})); + +export const ContentContainer = styled(Box)(() => ({ + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-evenly', + gap: '2.5rem', + width: '100%' +})); + +export const EmptyStateDiv = styled('div')(({ theme }) => ({ + backgroundColor: theme.palette.common.white, + textAlign: 'center', + borderRadius: '1rem', + width: '100%', + padding: '1.5rem', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center' +})); + +export const MainContainer = styled(Box)(({ theme }) => ({ + background: + theme.palette.mode === 'light' + ? theme.palette.background.default + : theme.palette.background.secondary, + paddingTop: theme.spacing(2), + borderRadius: '1rem', + marginBottom: theme.spacing(4), + display: 'flex', + alignItems: 'center', + flexDirection: 'column' +})); + +export const Title = styled(Typography)(({ theme }) => ({ + fontSize: '1.5rem', + fontWeight: 600, + color: theme.palette.text.default, + paddingLeft: theme.spacing(2), + display: 'flex', + alignItems: 'center', + gap: '0.5rem', + placeSelf: 'flex-start' +})); + +export const StyledCard = styled(Card)(({ theme }) => ({ + width: 'inherit', + minWidth: '150px', + borderRadius: '16px', + position: 'relative', + overflow: 'hidden', + transition: 'all 0.3s ease-in-out', + background: getCatalogCardBackground(theme.palette.mode === 'light'), + border: '1px solid transparent', + boxShadow: '2px 2px 3px 2px rgb(0, 211, 169, 0.5)', + '&:hover': { + transform: 'translateY(-4px)', + boxShadow: `2px 2px 3px 2px ${theme.palette.text.brand}`, + cursor: 'pointer' + } +})); + +export const CardSkeleton = styled('div')(() => ({ + display: 'flex', + gap: '10px', + flexWrap: 'nowrap', + justifyContent: 'center', + width: '100%' +})); + +export const IconContainer = styled(Box)(() => ({ + width: '2rem', + height: '2rem', + padding: '0.25rem', + borderRadius: '8px', + backgroundColor: '#D6FFF7', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + transition: 'all 0.3s ease', + '& svg': { + transition: 'transform 0.3s ease' + }, + '&:hover svg': { + transform: 'scale(1.2)' + }, + '& .clone-icon': { + width: '20px', + height: '20px' + } +})); + +export const ContentWrapper = styled(CardContent)(({ cardId, theme }) => ({ + height: '100%', + display: 'flex', + flexDirection: 'column', + padding: theme.spacing(2), + paddingInline: cardId === 'download-icon' ? '12px' : theme.spacing(2), + '&:last-child': { + paddingBottom: theme.spacing(2) + } +})); + +export const HeaderSection = styled(Box)({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'flex-start', + marginBottom: '1rem', + gap: '0.6rem' +}); + +export const HeaderTitle = styled(Typography)(({ theme }) => ({ + fontSize: '0.85rem', + fontWeight: 'bold', + color: theme.palette.text.default, + lineHeight: 1.2, + marginTop: '4px', + textTransform: 'uppercase', + letterSpacing: '0.5px' +})); + +export const StatsValue = styled(Typography)(({ theme }) => ({ + fontSize: '24px', + fontWeight: 700, + color: theme.palette.icon.secondary, + marginBottom: '0.5rem', + lineHeight: 1.2 +})); + +export const RepoSection = styled(Box)(({ theme }) => ({ + marginBlock: '.35rem', + padding: '8px', + borderRadius: '8px', + background: theme.palette.mode === 'light' ? '#f8fafc' : DARK_TEAL, + color: theme.palette.mode === 'light' ? 'rgba(26, 26, 26, .8)' : theme.palette.text.default, + transition: 'background 0.3s ease, filter 0.3s ease', + '&:hover': { + filter: 'brightness(0.98)' + } +})); + +export const RepoTitle = styled(Typography)(({ theme }) => ({ + fontSize: '0.9rem', + fontWeight: 1000, + color: theme.palette.text.default, + lineHeight: 1.3, + marginBottom: '4px', + display: '-webkit-box', + WebkitLineClamp: 2, + WebkitBoxOrient: 'vertical', + overflow: 'hidden', + textOverflow: 'ellipsis', + height: '2.6em' +})); + +export const UserNameText = styled(Typography)(({ theme }) => ({ + fontSize: '0.75rem', + color: + theme.palette.mode === 'light' + ? theme.palette.text.constant?.disabled + : theme.palette.text.disabled, + marginBottom: '8px', + transition: 'color 0.3s ease', + + '&:hover': { + color: theme.palette.text.brand + } +})); + +export const CardsContainer = styled(Box)(({ theme }) => ({ + display: 'flex', + gap: '18px', + width: '100%', + overflowX: 'auto', + padding: '18px', + background: + theme.palette.mode === 'light' + ? theme.palette.background.default + : theme.palette.background.secondary, + borderRadius: '12px', + boxShadow: '0 1px 3px rgba(0, 0, 0, 0.05)', + paddingBottom: theme.spacing(3) +})); + +export const StatusLabel = styled(Box)(({ labelType, theme }) => ({ + position: 'absolute', + bottom: 0, + left: 0, + background: + labelType === 'community' + ? 'rgba(122,132,142,.8)' + : labelType === 'official' + ? theme.palette.background.cta?.default + : theme.palette.text.brand, + color: labelType === 'official' ? 'black' : 'white', + paddingInline: '1rem', + borderTopRightRadius: '1rem', + fontSize: '0.75rem', + fontWeight: 'bold', + letterSpacing: '0.5px', + textTransform: 'lowercase', + zIndex: 2, + transition: 'all 0.3s ease', + '&:hover': { + filter: 'brightness(1.2)' + } +})); + +export const ErrorContainer = styled(Box)(({ theme }) => ({ + padding: '1rem', + color: theme.palette.text.error, + fontSize: '1rem', + fontWeight: 500 +})); From 411a49f6ddf15a108fc90335fa5ec07a642b4477 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:03:36 +0530 Subject: [PATCH 60/66] feat: add styles for PerformersSection component Signed-off-by: Amit Amrutiya --- src/custom/ResponsiveDataTable.tsx | 60 +++++++++++++++--------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index 230822db..de09a30b 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -310,42 +310,39 @@ const ResponsiveDataTable = ({ return new Intl.DateTimeFormat('en-US', dateOptions).format(date); }; - const updatedOptions = React.useMemo( - () => ({ - ...options, - print: false, - download: false, - search: false, - filter: false, - viewColumns: false, - rowsPerPageOptions: rowsPerPageOptions, - onViewColumnsChange: (column: string, action: string) => { - switch (action) { - case 'add': { - const colToAdd = columns.find((obj) => obj.name === column); - if (colToAdd) { - if (colToAdd.options) { - colToAdd.options.display = true; - updateCols && updateCols([...columns]); - } + const updatedOptions = { + ...options, + print: false, + download: false, + search: false, + filter: false, + viewColumns: false, + rowsPerPageOptions: rowsPerPageOptions, + onViewColumnsChange: (column: string, action: string) => { + switch (action) { + case 'add': { + const colToAdd = columns.find((obj) => obj.name === column); + if (colToAdd) { + if (colToAdd.options) { + colToAdd.options.display = true; + updateCols && updateCols([...columns]); } - break; } - case 'remove': { - const colToRemove = columns.find((obj) => obj.name === column); - if (colToRemove) { - if (colToRemove.options) { - colToRemove.options.display = false; - updateCols && updateCols([...columns]); - } + break; + } + case 'remove': { + const colToRemove = columns.find((obj) => obj.name === column); + if (colToRemove) { + if (colToRemove.options) { + colToRemove.options.display = false; + updateCols && updateCols([...columns]); } - break; } + break; } } - }), - [options, rowsPerPageOptions, columns, updateCols] - ); + } + }; const updateColumnsEffect = useCallback(() => { columns?.forEach((col) => { @@ -388,7 +385,8 @@ const ResponsiveDataTable = ({ } }); updateCols && updateCols([...columns]); - }, [columnVisibility, updateCols, columns]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [columnVisibility, updateCols]); React.useEffect(() => { updateColumnsEffect(); From 6d44e65331d53678e46a1161ac4c7f627b966260 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Tue, 19 Nov 2024 09:50:08 +0530 Subject: [PATCH 61/66] fix: table date and pagination issue Signed-off-by: Amit Amrutiya --- .../CatalogDesignTable/CatalogDesignTable.tsx | 135 ++++++++++++------ src/custom/TooltipIcon.tsx | 30 ++-- 2 files changed, 108 insertions(+), 57 deletions(-) diff --git a/src/custom/CatalogDesignTable/CatalogDesignTable.tsx b/src/custom/CatalogDesignTable/CatalogDesignTable.tsx index 8808b42d..74f4e441 100644 --- a/src/custom/CatalogDesignTable/CatalogDesignTable.tsx +++ b/src/custom/CatalogDesignTable/CatalogDesignTable.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import _ from 'lodash'; -import { useEffect, useRef, useState } from 'react'; +import { useCallback, useMemo, useRef } from 'react'; import { PublishIcon } from '../../icons'; import { CHARCOAL, useTheme } from '../../theme'; import { Pattern } from '../CustomCatalog/CustomCard'; @@ -47,28 +47,54 @@ export const CatalogDesignsTable: React.FC = ({ handleBulkDeleteModal, handleBulkpatternsDataUnpublishModal }) => { - const [tableCols, updateCols] = useState>([]); const { width } = useWindowDimensions(); const smallScreen = width <= 360; const theme = useTheme(); const modalRef = useRef(null); - useEffect(() => { - if (Array.isArray(columns) && columns.length > 0) { - updateCols(columns); - } - }, [columns]); + const formatDate = useCallback((date: string | Date): string => { + const dateOptions: Intl.DateTimeFormatOptions = { + weekday: 'short', + day: 'numeric', + month: 'long', + year: 'numeric' + }; + return new Date(date).toLocaleDateString('en-US', dateOptions); + }, []); + + const processedColumns = useMemo(() => { + return columns.map((col) => { + const newCol = { ...col }; + if (!newCol.options) newCol.options = {}; + newCol.options.display = columnVisibility[col.name]; + if ( + [ + 'updated_at', + 'created_at', + 'deleted_at', + 'last_login_time', + 'joined_at', + 'last_run', + 'next_run' + ].includes(col.name) + ) { + newCol.options.customBodyRender = (value: any) => { + if (!value || value === 'NA') return <>NA; + if (typeof value === 'object' && 'Valid' in value) { + if (value.Valid && value.Time) { + return <>{formatDate(value.Time)}; + } + return <>NA; + } + return <>{formatDate(value)}; + }; + } + return newCol; + }); + }, [columns, columnVisibility, formatDate]); - const options: any = { - selectableRows: _.isNil(filter) ? 'none' : 'multiple', - serverSide: true, - filterType: 'multiselect', - responsive: smallScreen ? 'vertical' : 'standard', - count: totalCount, - rowsPerPage: pageSize, - page, - elevation: 0, - onTableChange: (action: string, tableState: any) => { + const handleTableChange = useCallback( + (action: string, tableState: any) => { const sortInfo = tableState.announceText ? tableState.announceText.split(' : ') : []; let order = ''; if (tableState.activeColumn) { @@ -98,29 +124,57 @@ export const CatalogDesignsTable: React.FC = ({ } break; } - } - }; + }, + [columns, setPage, setPageSize, setSortOrder, sortOrder] + ); - 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; - }; - } + const options = useMemo( + () => ({ + selectableRows: _.isNil(filter) ? 'none' : 'multiple', + serverSide: true, + filterType: 'multiselect', + responsive: smallScreen ? 'vertical' : 'standard', + count: totalCount, + rowsPerPage: pageSize, + page, + elevation: 0, + onTableChange: handleTableChange, + customToolbarSelect: _.isNil(filter) + ? (selected: any) => ( + handleBulkpatternsDataUnpublishModal(selected, patterns, modalRef)} + iconType="publish" + id={'unpublish-button'} + > + + + ) + : undefined, + onRowsDelete: !_.isNil(filter) + ? (rowsDeleted: any) => { + const selectedPatterns = rowsDeleted.data.map( + ({ dataIndex }: any) => patterns[dataIndex] + ); + handleBulkDeleteModal(selectedPatterns, modalRef); + return false; + } + : undefined + }), + [ + filter, + smallScreen, + totalCount, + pageSize, + page, + handleTableChange, + patterns, + handleBulkDeleteModal, + handleBulkpatternsDataUnpublishModal + ] + ); - if (!Array.isArray(tableCols) || tableCols.length === 0) { + if (!processedColumns.length) { return null; } @@ -128,14 +182,13 @@ export const CatalogDesignsTable: React.FC = ({ <> -
    - - {icon} - -
    + borderRadius: '4px' + }, + ...(style as SxProps) + }} + disableRipple + > + {icon} + ); } From b0b842b931c620683a5476677ddb0b8019b49126 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Tue, 19 Nov 2024 15:37:28 +0530 Subject: [PATCH 62/66] feat: add AuthorCell component and integrate it into CatalogDesignTable Signed-off-by: Amit Amrutiya --- src/custom/CatalogDesignTable/AuthorCell.tsx | 66 +++++++++++++++++++ .../CatalogDesignTable/CatalogDesignTable.tsx | 11 ++-- .../CatalogDesignTable/columnConfig.tsx | 51 +++----------- src/custom/CatalogDesignTable/index.ts | 3 +- 4 files changed, 80 insertions(+), 51 deletions(-) create mode 100644 src/custom/CatalogDesignTable/AuthorCell.tsx diff --git a/src/custom/CatalogDesignTable/AuthorCell.tsx b/src/custom/CatalogDesignTable/AuthorCell.tsx new file mode 100644 index 00000000..bf8a7ed8 --- /dev/null +++ b/src/custom/CatalogDesignTable/AuthorCell.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { Avatar, Box, Grid, Typography } from '../../base'; +import { CLOUD_URL } from '../../constants/constants'; +import { PersonIcon } from '../../icons'; +import { CustomTooltip } from '../CustomTooltip'; + +interface AuthorCellProps { + firstName: string; + lastName: string; + avatarUrl: string; + userId: string; + maxWidth?: boolean; +} + +const AuthorCell: React.FC = ({ + firstName, + lastName, + avatarUrl, + userId, + maxWidth = true +}) => { + const displayName = + firstName && lastName + ? `${firstName} ${lastName}` + : firstName + ? firstName + : lastName + ? lastName + : ''; + + return ( + img': { mr: 2, flexShrink: 0 } }}> + + + + +
    + { + window.open(`${CLOUD_URL}/user/${userId}`, '_blank'); + }} + > + {!avatarUrl && } + +
    +
    +
    +
    + {maxWidth && ( + + {displayName} + + )} +
    +
    + ); +}; + +export default AuthorCell; diff --git a/src/custom/CatalogDesignTable/CatalogDesignTable.tsx b/src/custom/CatalogDesignTable/CatalogDesignTable.tsx index 74f4e441..42d9c111 100644 --- a/src/custom/CatalogDesignTable/CatalogDesignTable.tsx +++ b/src/custom/CatalogDesignTable/CatalogDesignTable.tsx @@ -4,7 +4,7 @@ import { useCallback, useMemo, useRef } from 'react'; import { PublishIcon } from '../../icons'; import { CHARCOAL, useTheme } from '../../theme'; import { Pattern } from '../CustomCatalog/CustomCard'; -import { useWindowDimensions } from '../Helpers/Dimension'; +import { ErrorBoundary } from '../ErrorBoundary'; import PromptComponent from '../Prompt'; import { PromptRef } from '../Prompt/promt-component'; import ResponsiveDataTable from '../ResponsiveDataTable'; @@ -47,8 +47,6 @@ export const CatalogDesignsTable: React.FC = ({ handleBulkDeleteModal, handleBulkpatternsDataUnpublishModal }) => { - const { width } = useWindowDimensions(); - const smallScreen = width <= 360; const theme = useTheme(); const modalRef = useRef(null); @@ -133,7 +131,7 @@ export const CatalogDesignsTable: React.FC = ({ selectableRows: _.isNil(filter) ? 'none' : 'multiple', serverSide: true, filterType: 'multiselect', - responsive: smallScreen ? 'vertical' : 'standard', + responsive: 'standard', count: totalCount, rowsPerPage: pageSize, page, @@ -163,7 +161,6 @@ export const CatalogDesignsTable: React.FC = ({ }), [ filter, - smallScreen, totalCount, pageSize, page, @@ -179,7 +176,7 @@ export const CatalogDesignsTable: React.FC = ({ } return ( - <> + = ({ : theme.palette.background.secondary } /> - + ); }; diff --git a/src/custom/CatalogDesignTable/columnConfig.tsx b/src/custom/CatalogDesignTable/columnConfig.tsx index 84416a36..549fd081 100644 --- a/src/custom/CatalogDesignTable/columnConfig.tsx +++ b/src/custom/CatalogDesignTable/columnConfig.tsx @@ -2,8 +2,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { MUIDataTableColumn, MUIDataTableMeta } from 'mui-datatables'; import { FacebookShareButton, LinkedinShareButton, TwitterShareButton } from 'react-share'; -import { Avatar, Box, Grid, Typography } from '../../base'; -import { CLOUD_URL } from '../../constants/constants'; import { iconMedium } from '../../constants/iconsSizes'; import { ChainIcon, @@ -12,16 +10,15 @@ import { 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 AuthorCell from './AuthorCell'; import { NameDiv } from './style'; export type ColView = [string, 'na' | 'xs' | 'l']; @@ -141,47 +138,15 @@ export const createDesignColumns = ({ 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.open(`${CLOUD_URL}/user/${user_id}`, '_blank'); - }} - > - {!avatar_url && } - -
    -
    -
    -
    - {maxWidth && ( - - {displayName} - - )} -
    -
    + ); } } diff --git a/src/custom/CatalogDesignTable/index.ts b/src/custom/CatalogDesignTable/index.ts index fcab0208..98c1393f 100644 --- a/src/custom/CatalogDesignTable/index.ts +++ b/src/custom/CatalogDesignTable/index.ts @@ -1,5 +1,6 @@ +import AuthorCell from './AuthorCell'; import CatalogDesignsTable from './CatalogDesignTable'; import { colViews, createDesignColumns } from './columnConfig'; export { TableVisibilityControl } from './TableVisibilityControl'; export { ViewSwitch } from './ViewSwitch'; -export { CatalogDesignsTable, colViews, createDesignColumns }; +export { AuthorCell, CatalogDesignsTable, colViews, createDesignColumns }; From 88e0bd309a7acf74968d58d03bef30d07e8f9154 Mon Sep 17 00:00:00 2001 From: Lee Calcote Date: Wed, 20 Nov 2024 13:59:30 -0600 Subject: [PATCH 63/66] fix: Share icon is in outline format, not filled Fixes #817 Signed-off-by: Lee Calcote --- src/icons/Share/ShareIcon.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/icons/Share/ShareIcon.tsx b/src/icons/Share/ShareIcon.tsx index 758f1fa9..f4120d6d 100644 --- a/src/icons/Share/ShareIcon.tsx +++ b/src/icons/Share/ShareIcon.tsx @@ -18,7 +18,7 @@ export const ShareIcon: FC = ({ d="M11.5 4.95703V5.39068L11.0707 5.45201C7.68596 5.93554 5.29546 7.37866 3.62629 9.28628C2.43591 10.6467 1.60118 12.2567 1.04239 13.9499C3.51457 11.4886 6.75712 10.357 11 10.357H11.5V10.857V13.7499L17.2929 7.95703L11.5 2.16414V4.95703Z" stroke={fill} strokeWidth={1.5} - fill="none" + fill={fill} /> ); From ed6b8b125e59cf9ced9dae2aa797e163e6f4eb96 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Thu, 21 Nov 2024 12:56:41 +0530 Subject: [PATCH 64/66] feat: standardize font family to inherit across multiple components Signed-off-by: Amit Amrutiya --- .../CatalogDetail/CollapsibleSection.tsx | 10 +++++- .../InputSearchField/InputSearchField.tsx | 5 +++ src/custom/Markdown/style.tsx | 36 ++++++++++++------- .../UserSearchField/UserSearchFieldInput.tsx | 5 +++ 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/custom/CatalogDetail/CollapsibleSection.tsx b/src/custom/CatalogDetail/CollapsibleSection.tsx index 49c41794..a356f301 100644 --- a/src/custom/CatalogDetail/CollapsibleSection.tsx +++ b/src/custom/CatalogDetail/CollapsibleSection.tsx @@ -38,7 +38,12 @@ const CollapsibleSection: React.FC = ({ {isOpen ? : } - + {items && items.length > 0 ? ( {items?.map(renderItem)} @@ -50,6 +55,9 @@ const CollapsibleSection: React.FC = ({ opacity: 0.8, padding: '7px' }} + primaryTypographyProps={{ + fontFamily: 'inherit' + }} primary={emptyState} /> )} diff --git a/src/custom/InputSearchField/InputSearchField.tsx b/src/custom/InputSearchField/InputSearchField.tsx index c6f9c647..b880049e 100644 --- a/src/custom/InputSearchField/InputSearchField.tsx +++ b/src/custom/InputSearchField/InputSearchField.tsx @@ -127,6 +127,11 @@ const InputSearchField: React.FC = ({ error={!!error} helperText={error} fullWidth + InputLabelProps={{ + style: { + fontFamily: 'inherit' + } + }} InputProps={{ ...params.InputProps, endAdornment: ( diff --git a/src/custom/Markdown/style.tsx b/src/custom/Markdown/style.tsx index 2043d283..5af5c13b 100644 --- a/src/custom/Markdown/style.tsx +++ b/src/custom/Markdown/style.tsx @@ -7,7 +7,8 @@ export const StyledMarkdown = styled('a')(({ theme }) => ({ '&:hover': { textDecoration: 'underline' }, - cursor: 'pointer' + cursor: 'pointer', + fontFamily: 'inherit' })); // anchor style for notifications markdown content @@ -28,31 +29,38 @@ export const StyledMarkdownP = styled('p')(({ theme }) => ({ export const StyledMarkdownTooltipP = styled('p')(({ theme }) => ({ color: theme.palette.text.constant?.white || text.inverse, - marginBlock: '0px' + marginBlock: '0px', + fontFamily: 'inherit' })); export const StyledMarkdownH1 = styled('h1')(({ theme }) => ({ - color: theme.palette.text.default + color: theme.palette.text.default, + fontFamily: 'inherit' })); export const StyledMarkdownH2 = styled('h2')(({ theme }) => ({ - color: theme.palette.text.default + color: theme.palette.text.default, + fontFamily: 'inherit' })); export const StyledMarkdownH3 = styled('h3')(({ theme }) => ({ - color: theme.palette.text.default + color: theme.palette.text.default, + fontFamily: 'inherit' })); export const StyledMarkdownH4 = styled('h4')(({ theme }) => ({ - color: theme.palette.text.default + color: theme.palette.text.default, + fontFamily: 'inherit' })); export const StyledMarkdownH5 = styled('h5')(({ theme }) => ({ - color: theme.palette.text.default + color: theme.palette.text.default, + fontFamily: 'inherit' })); export const StyledMarkdownH6 = styled('h6')(({ theme }) => ({ - color: theme.palette.text.default + color: theme.palette.text.default, + fontFamily: 'inherit' })); export const StyledMarkdownBlockquote = styled('blockquote')(({ theme }) => ({ @@ -67,22 +75,26 @@ export const StyledMarkdownUl = styled('ul')(({ theme }) => ({ export const StyledMarkdownLi = styled('li')(({ theme }) => ({ color: theme.palette.text.default, - ...theme.typography.textB1Regular + ...theme.typography.textB1Regular, + fontFamily: 'inherit' })); export const StyledMarkdownTh = styled('th')(({ theme }) => ({ color: theme.palette.text.default, ...theme.typography.textH3Medium, - marginBlock: '0px' + marginBlock: '0px', + fontFamily: 'inherit' })); export const StyledMarkdownTd = styled('td')(({ theme }) => ({ color: theme.palette.text.default, marginBlock: '0px', - ...theme.typography.textB1Regular + ...theme.typography.textB1Regular, + fontFamily: 'inherit' })); export const StyledMarkdownPre = styled('pre')(({ theme }) => ({ background: theme.palette.background.code, - whiteSpace: 'pre-line' + whiteSpace: 'pre-line', + fontFamily: 'inherit' })); diff --git a/src/custom/UserSearchField/UserSearchFieldInput.tsx b/src/custom/UserSearchField/UserSearchFieldInput.tsx index c2f79b07..67e747e2 100644 --- a/src/custom/UserSearchField/UserSearchFieldInput.tsx +++ b/src/custom/UserSearchField/UserSearchFieldInput.tsx @@ -194,6 +194,11 @@ const UserSearchField: React.FC = ({ label={label} error={!!error} helperText={error} + InputLabelProps={{ + style: { + fontFamily: 'inherit' + } + }} InputProps={{ ...params.InputProps, endAdornment: ( From a73a822581c50392e4bb74e71f0115afc4e06506 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Thu, 21 Nov 2024 13:03:00 +0530 Subject: [PATCH 65/66] feat: replace Tooltip with CustomTooltip and update icon colors in SocialSharePopper Signed-off-by: Amit Amrutiya --- src/custom/CatalogDetail/SocialSharePopper.tsx | 15 ++++++++------- src/custom/CatalogDetail/style.tsx | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/custom/CatalogDetail/SocialSharePopper.tsx b/src/custom/CatalogDetail/SocialSharePopper.tsx index 3c24b32d..01baabd5 100644 --- a/src/custom/CatalogDetail/SocialSharePopper.tsx +++ b/src/custom/CatalogDetail/SocialSharePopper.tsx @@ -1,9 +1,10 @@ -import { Box, IconButton, Menu, MenuItem, Tooltip } from '@mui/material'; +import { Box, IconButton, Menu, MenuItem } from '@mui/material'; import React, { useState } from 'react'; import { FacebookShareButton, LinkedinShareButton, TwitterShareButton } from 'react-share'; import { ChainIcon, FacebookIcon, LinkedinIcon, ShareIcon, TwitterIcon } from '../../icons'; import { useTheme } from '../../theme'; import { Pattern } from '../CustomCatalog/CustomCard'; +import { CustomTooltip } from '../CustomTooltip'; import { ErrorBoundary } from '../ErrorBoundary'; import { CopyShareIconWrapper, VisibilityChip } from './style'; @@ -50,23 +51,23 @@ const SocialSharePopper: React.FC = ({ {details?.visibility !== 'private' && ( - + handleCopyUrl(cleanedType, details?.name, details?.id)} > - + - + )} {(details?.visibility === 'published' || details?.visibility === 'public') && ( <> - + - + - + ({ letterSpacing: '0.15px', lineHeight: '1.5', textTransform: 'lowercase', - color: theme.palette.background.supplementary, + color: theme.palette.icon.secondary, [' @media (max-width: 285px)']: { fontSize: '0.86rem' } })); export const MetricsData = styled('div')(({ theme }) => ({ - color: theme.palette.background.supplementary, + color: theme.palette.icon.secondary, fontSize: '1.2rem', fontWeight: 'bold', lineHeight: '1.5' From 49a2ccb992e25a5192501c6e88c82da98777a3d8 Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Fri, 22 Nov 2024 18:13:20 +0530 Subject: [PATCH 66/66] feat(icon): headericon for prompt Signed-off-by: Sudhanshu Dasgupta --- src/custom/Prompt/promt-component.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/custom/Prompt/promt-component.tsx b/src/custom/Prompt/promt-component.tsx index 44022d73..90824d95 100644 --- a/src/custom/Prompt/promt-component.tsx +++ b/src/custom/Prompt/promt-component.tsx @@ -25,6 +25,7 @@ interface State { primaryOption: string; showInfoIcon?: string; variant?: PromptVariant; + headerIcon?: React.ReactNode; } interface ShowParams { @@ -33,6 +34,7 @@ interface ShowParams { primaryOption: string; variant: PromptVariant; showInfoIcon?: string; + headerIcon?: React.ReactNode; } export interface PromptRef { @@ -46,7 +48,8 @@ const PromptComponent = forwardRef(({ variant }, ref) => subtitle: '', primaryOption: '', showInfoIcon: '', - variant + variant, + headerIcon: undefined }); /* This ref is used to store the resolve and reject functions of the promise returned by the show method */ @@ -78,7 +81,7 @@ const PromptComponent = forwardRef(({ variant }, ref) => show })); - const { isOpen, primaryOption, title, subtitle, showInfoIcon } = state; + const { isOpen, primaryOption, title, subtitle, showInfoIcon, headerIcon } = state; const { resolve } = promiseInfoRef.current; return ( @@ -87,7 +90,7 @@ const PromptComponent = forwardRef(({ variant }, ref) => closeModal={hide} title={title} id="searchClick" - headerIcon={undefined} + headerIcon={headerIcon} reactNode={undefined} > {subtitle && (