Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/__testing__/ResponsiveDataTable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ jest.mock('@sistent/mui-datatables', () => {
};
});

// eslint-disable-next-line import/first
import ResponsiveDataTable from '../custom/ResponsiveDataTable';

const mockColumns = [
Expand Down
2 changes: 1 addition & 1 deletion src/__testing__/routing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('routing utilities', () => {
expect(getShareableResourceRoute(RESOURCE_TYPE.DESIGN, 'd2', 'design')).toBe(
'http://localhost/workspace?mode=design&design=d2'
);
expect(() => getShareableResourceRoute('filter' as any, 'f1', 'filter')).toThrow(
expect(() => getShareableResourceRoute('filter' as unknown as RESOURCE_TYPE, 'f1', 'filter')).toThrow(
'Unknown resource type filter'
);
});
Expand Down
4 changes: 2 additions & 2 deletions src/actors/worker/workerfy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ export const workerfyActor = (actor: AnyActorLogic) => {
}

if (event.data.type === WORKER_COMMANDS.STOP_ACTOR) {
snapshotSubscription?.unsubscribe && snapshotSubscription.unsubscribe();
actorRef?.stop && actorRef.stop();
snapshotSubscription?.unsubscribe?.();
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The double optional chaining ?.unsubscribe?.() is unnecessary. The Subscription type from xstate guarantees that unsubscribe is a method on the object. Since snapshotSubscription can be null, only the first optional chaining is needed: snapshotSubscription?.unsubscribe(). The second optional chaining adds no value and suggests the method might not exist, which is not the case.

Suggested change
snapshotSubscription?.unsubscribe?.();
snapshotSubscription?.unsubscribe();

Copilot uses AI. Check for mistakes.
actorRef?.stop?.();
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The double optional chaining ?.stop?.() is unnecessary. The AnyActorRef type from xstate guarantees that stop is a method on the object. Since actorRef can be null, only the first optional chaining is needed: actorRef?.stop(). The second optional chaining adds no value and suggests the method might not exist, which is not the case.

Suggested change
actorRef?.stop?.();
actorRef?.stop();

Copilot uses AI. Check for mistakes.
}

if (event.data.type === WORKER_COMMANDS.SEND_EVENT) {
Expand Down
2 changes: 1 addition & 1 deletion src/base/Hidden/Hidden.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import React from 'react';

export const Hidden = React.forwardRef<HTMLDivElement, MuiHiddenProps>((props, ref) => {
return React.cloneElement(<MuiHidden {...props} />, { ref });
return <MuiHidden ref={ref} {...props} />;

Check failure on line 5 in src/base/Hidden/Hidden.tsx

View workflow job for this annotation

GitHub Actions / compatibility-check (22)

Type '{ children?: ReactNode; implementation?: "js" | "css" | undefined; initialWidth?: Breakpoint | undefined; lgDown?: boolean | undefined; lgUp?: boolean | undefined; ... 9 more ...; ref: ForwardedRef<...>; }' is not assignable to type 'IntrinsicAttributes & HiddenProps'.

Check failure on line 5 in src/base/Hidden/Hidden.tsx

View workflow job for this annotation

GitHub Actions / compatibility-check (20)

Type '{ children?: ReactNode; implementation?: "js" | "css" | undefined; initialWidth?: Breakpoint | undefined; lgDown?: boolean | undefined; lgUp?: boolean | undefined; ... 9 more ...; ref: ForwardedRef<...>; }' is not assignable to type 'IntrinsicAttributes & HiddenProps'.
});

export default Hidden;
2 changes: 1 addition & 1 deletion src/custom/CatalogDesignTable/CatalogDesignTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const CatalogDesignsTable: React.FC<CatalogDesignsTableProps> = ({
setPageSize(tableState.rowsPerPage);
break;
case 'search':
setSearch && setSearch(tableState.searchText !== null ? tableState.searchText : '');
setSearch?.(tableState.searchText !== null ? tableState.searchText : '');
break;
case 'sort':
if (
Expand Down
20 changes: 9 additions & 11 deletions src/custom/CatalogDetail/ChallengesSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { Link, ListItemIcon } from '../../base';
import { MESHERY_CLOUD_PROD } from '../../constants/constants';
import { ChallengesIcon } from '../../icons';
Expand All @@ -14,18 +14,16 @@ interface ChallengesSectionProps {

const ChallengesSection: React.FC<ChallengesSectionProps> = ({ filteredAcademyData }) => {
const theme = useTheme();
const [openChallenges, setOpenChallenges] = useState(false);
const challenges =
filteredAcademyData?.['challenges'] ?? filteredAcademyData?.['challenge'] ?? [];
const hasChallenges = challenges.length > 0;
const [openChallenges, setOpenChallenges] = useState(hasChallenges);
const [autoUpdate, setAutoUpdate] = useState(true);

useEffect(() => {
if (autoUpdate) {
setOpenChallenges((filteredAcademyData?.['challenges'] ?? []).length > 0);
}
}, [filteredAcademyData, autoUpdate]);
const isOpen = autoUpdate ? hasChallenges : openChallenges;

const toggleOpenChallenges = () => {
setOpenChallenges((prev) => !prev);
setAutoUpdate(false);
setOpenChallenges(!isOpen);
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toggle logic has a race condition. When toggling, setOpenChallenges(!isOpen) uses the value of isOpen which is derived from autoUpdate and other state. If autoUpdate is true when the function runs, isOpen will be hasChallenges, not openChallenges. This means the toggle won't work correctly after the first click. The fix should read the previous state value: setOpenChallenges((prev) => !prev) to ensure proper toggle behavior.

Suggested change
setOpenChallenges(!isOpen);
setOpenChallenges((prev) => !prev);

Copilot uses AI. Check for mistakes.
};

const renderChallengeItem = (item: string, index: number) => (
Expand Down Expand Up @@ -61,9 +59,9 @@ const ChallengesSection: React.FC<ChallengesSectionProps> = ({ filteredAcademyDa
/>
<CollapsibleSection
title="Challenges"
isOpen={openChallenges}
isOpen={isOpen}
onToggle={toggleOpenChallenges}
items={filteredAcademyData['challenge'] ?? []}
items={challenges}
renderItem={renderChallengeItem}
tooltip="Learn CNCF projects by taking and completing time-based, hands-on labs. [Browse all challenges](/academy/challenges)"
emptyState="No active challenges for this technology"
Expand Down
9 changes: 3 additions & 6 deletions src/custom/CatalogDetail/ContentClassInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,8 @@ const ContentClassInfo: React.FC<ContentClassInfoProps> = ({ contentClass, class
}
} as const;

const ClassIcon: React.FC<{ className: string }> = ({ className }) => {
const Icon = CONTENT_CLASS[className]?.icon;
const fill = CONTENT_CLASS[className]?.color;
return Icon ? <Icon width="25px" height="25px" fill={fill} /> : null;
};
const Icon = CONTENT_CLASS[contentClass]?.icon;
const fill = CONTENT_CLASS[contentClass]?.color;

return (
<div>
Expand All @@ -61,7 +58,7 @@ const ContentClassInfo: React.FC<ContentClassInfoProps> = ({ contentClass, class
fontFamily: 'inherit'
}}
>
<ClassIcon className={contentClass} />
{Icon ? <Icon width="25px" height="25px" fill={fill} /> : null}
{formatToTitleCase(contentClass)}
</ContentDetailsText>
</div>
Expand Down
16 changes: 6 additions & 10 deletions src/custom/CatalogDetail/LearningSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useState } from 'react';
import { Link, ListItemIcon } from '../../base';
import { MESHERY_CLOUD_PROD } from '../../constants/constants';
import { LearningIcon } from '../../icons';
Expand All @@ -14,18 +14,14 @@ interface LearningSectionProps {

const LearningSection: React.FC<LearningSectionProps> = ({ filteredAcademyData }) => {
const theme = useTheme();
const [openLearning, setOpenLearning] = useState<boolean>(false);
const hasLearning = Boolean((filteredAcademyData?.['learning-path'] ?? []).length > 0);
const [openLearning, setOpenLearning] = useState<boolean>(hasLearning);
const [autoUpdate, setAutoUpdate] = useState<boolean>(true);

useEffect(() => {
if (autoUpdate) {
setOpenLearning(Boolean((filteredAcademyData?.['learning-path'] ?? []).length > 0));
}
}, [filteredAcademyData, autoUpdate]);
const isOpen = autoUpdate ? hasLearning : openLearning;

const toggleOpenLearning = (): void => {
setOpenLearning((prev) => !prev);
setAutoUpdate(false);
setOpenLearning(!isOpen);
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toggle logic has a race condition. When toggling, setOpenLearning(!isOpen) uses the value of isOpen which is derived from autoUpdate and other state. If autoUpdate is true when the function runs, isOpen will be hasLearning, not openLearning. This means the toggle won't work correctly after the first click. The fix should read the previous state value: setOpenLearning((prev) => !prev) to ensure proper toggle behavior.

Suggested change
setOpenLearning(!isOpen);
setOpenLearning((prev) => !prev);

Copilot uses AI. Check for mistakes.
};

const renderLearningItem = (item: string, index: number) => (
Expand Down Expand Up @@ -60,7 +56,7 @@ const LearningSection: React.FC<LearningSectionProps> = ({ filteredAcademyData }
/>
<CollapsibleSection
title="Learning Paths"
isOpen={openLearning}
isOpen={isOpen}
onToggle={toggleOpenLearning}
items={filteredAcademyData['learning-path'] || []}
renderItem={renderLearningItem}
Expand Down
9 changes: 4 additions & 5 deletions src/custom/CustomCatalog/CatalogCardDesignLogo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,12 @@ const CatalogCardDesignLogo: React.FC<CatalogCardDesignLogoProps> = ({
setIsZoomed(false);
};

const SvgComponent: React.FC<{ type: { type: string } }> = ({ type }) => {
return type.type === 'filter' ? (
const renderSvg =
type.type === 'filter' ? (
<MesheryFilterIcon width={width} height={height} style={style} />
) : (
<DesignIcon width={width} height={height} style={style} />
);
};

return (
<>
Expand Down Expand Up @@ -82,11 +81,11 @@ const CatalogCardDesignLogo: React.FC<CatalogCardDesignLogoProps> = ({
</Dialog>
</>
) : (
<SvgComponent type={type} />
renderSvg
)}
</div>
) : (
<SvgComponent type={type} />
renderSvg
)}
</>
);
Expand Down
4 changes: 2 additions & 2 deletions src/custom/FlipCard/FlipCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ export function FlipCard({
onClick={() => {
if (disableFlip) return;
setFlipped((flipped) => !flipped);
onClick && onClick();
onShow && onShow();
onClick?.();
onShow?.();
}}
>
<InnerCard
Expand Down
Loading