Skip to content

Commit 05acb99

Browse files
fix(frontend): topic-list error fix + dependency & code-health cleanup (#2501)
* chore(frontend): remove six unused dependencies Drop moment, react-draggable, jwt-decode, chakra-react-select, @autoform/react, and @autoform/zod — zero imports across the frontend (audit finding DEPS-01). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(frontend): extract named cache-policy stale-time constants Replace inline staleTime magic numbers with named constants (DEFAULT_QUERY_STALE_TIME, TOPIC_CONFIG_STALE_TIME) reusing the existing *_LIVED_CACHE_STALE_TIME convention. Values are unchanged (audit DATA-04). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(frontend): type-check ACL query inputs instead of casting Drop four `{} as ListACLsRequest` casts on connect-query listACLs calls so the request shape is checked against the proto, and remove the now-unused ListACLsRequest imports (audit DATA-05). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(frontend): remove dead commented-out MobX demo block Delete the 90-line commented AnimationExample (observer/observable) from animation-props.tsx. No MobX references remain in src (audit LEGACY-08). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): surface HTTP errors in the legacy topic list query useLegacyListTopicsQuery used window.fetch, which does not reject on 4xx/5xx, and returned response.json() unguarded — so a 403/500 with a JSON body parsed as a successful empty result and the topics page silently rendered 0 topics instead of an error. Guard on response.ok and add a regression test covering the error and success paths (audit BUGS-01). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): stop logging document URLs during topic-doc render Remove a console.log that printed every transformed link/image URL from backend-supplied topic documentation on each render. The sanitizeUrl logic is unchanged (audit SECURITY-02). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(frontend): set ok:true on add-topic-step topic-list fetch mocks The BUGS-01 fix makes useLegacyListTopicsQuery guard response.ok, so the config.fetch success mocks must mirror a real Response (ok:true) — otherwise the guard throws and existing-topic detection breaks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(frontend): align cache-constant naming and clarify fetch comment Address @claude review nits: rename DEFAULT_QUERY_STALE_TIME -> DEFAULT_CACHE_STALE_TIME and TOPIC_CONFIG_STALE_TIME -> TOPIC_CONFIG_CACHE_STALE_TIME to match the existing *_CACHE_STALE_TIME convention, and reword the topic.tsx comment to reference config.fetch (not window.fetch). No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent fa178a7 commit 05acb99

14 files changed

Lines changed: 114 additions & 160 deletions

File tree

frontend/bun.lock

Lines changed: 2 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@
4949
},
5050
"dependencies": {
5151
"@a2a-js/sdk": "^0.3.13",
52-
"@autoform/react": "^4.0.0",
53-
"@autoform/zod": "^5.0.0",
5452
"@base-ui/react": "^1.5.0",
5553
"@buf/redpandadata_cloud.connectrpc_query-es": "^2.2.0-20251128173054-b9f9fc6e5a70.1",
5654
"@buf/redpandadata_common.bufbuild_es": "^2.11.0-20260316210807-5d899910f714.1",
@@ -89,7 +87,6 @@
8987
"@xyflow/react": "^12.9.2",
9088
"ai": "^6.0.168",
9189
"array-move": "^4.0.0",
92-
"chakra-react-select": "5.0.5",
9390
"class-variance-authority": "^0.7.1",
9491
"clsx": "^2.1.1",
9592
"cmdk": "^1.1.1",
@@ -102,7 +99,6 @@
10299
"hast-util-to-jsx-runtime": "^2.3.6",
103100
"js-base64": "^3.7.8",
104101
"json-bigint": "^1.0.0",
105-
"jwt-decode": "^4.0.0",
106102
"lottie-react": "^2.4.1",
107103
"lucide-react": "^1.17.0",
108104
"monaco-editor": "^0.54.0",
@@ -119,7 +115,6 @@
119115
"react-compiler-runtime": "^1.0.0",
120116
"react-day-picker": "^9.14.0",
121117
"react-dom": "^18.3.1",
122-
"react-draggable": "^4.5.0",
123118
"react-dropzone": "^15.0.0",
124119
"react-highlight-words": "^0.21.0",
125120
"react-hook-form": "^7.72.0",

frontend/src/components/pages/rp-connect/onboarding/add-topic-step.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,15 @@ describe('AddTopicStep', () => {
115115
mockFetch.mockReset();
116116
// Default: return empty topic list
117117
mockFetch.mockResolvedValue({
118+
ok: true,
118119
json: () => Promise.resolve(createTopicsResponse([])),
119120
});
120121
});
121122

122123
it('existing topic returns name via triggerSubmit', async () => {
123124
const user = userEvent.setup();
124125
mockFetch.mockResolvedValue({
126+
ok: true,
125127
json: () => Promise.resolve(createTopicsResponse(['my-topic', 'other-topic'])),
126128
});
127129

@@ -284,6 +286,7 @@ describe('AddTopicStep', () => {
284286

285287
it('selectionMode=existing shows combobox', async () => {
286288
mockFetch.mockResolvedValue({
289+
ok: true,
287290
json: () => Promise.resolve(createTopicsResponse(['topic-a'])),
288291
});
289292
const transport = createTransport();
@@ -297,6 +300,7 @@ describe('AddTopicStep', () => {
297300
it('existing topic alert shown in create mode when name matches', async () => {
298301
const user = userEvent.setup();
299302
mockFetch.mockResolvedValue({
303+
ok: true,
300304
json: () => Promise.resolve(createTopicsResponse(['existing-topic'])),
301305
});
302306
const transport = createTransport();
@@ -356,6 +360,7 @@ describe('AddTopicStep', () => {
356360

357361
it('selectionMode=both renders toggle group', async () => {
358362
mockFetch.mockResolvedValue({
363+
ok: true,
359364
json: () => Promise.resolve(createTopicsResponse(['t1'])),
360365
});
361366
const transport = createTransport();

frontend/src/components/pages/security/hooks/use-principal-permissions.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ import { useMemo } from 'react';
1414
import { useStore } from 'zustand';
1515

1616
import { usePrincipalList } from './use-principal-list';
17-
import {
18-
ACL_PermissionType,
19-
ACL_ResourceType,
20-
type ListACLsRequest,
21-
} from '../../../../protogen/redpanda/api/dataplane/v1/acl_pb';
17+
import { ACL_PermissionType, ACL_ResourceType } from '../../../../protogen/redpanda/api/dataplane/v1/acl_pb';
2218
import { listACLs } from '../../../../protogen/redpanda/api/dataplane/v1/acl-ACLService_connectquery';
2319
import { getACLOperation } from '../../../../react-query/api/acl';
2420
import { type RolePrincipal, useRolesStore } from '../../../../state/backend-api';
@@ -58,7 +54,7 @@ const RESOURCE_TYPE_LABELS: Partial<Record<ACL_ResourceType, string>> = {
5854
};
5955

6056
export function useUserPermissions(userName: string) {
61-
const { data: allAclsData, isLoading } = useQuery(listACLs, {} as ListACLsRequest);
57+
const { data: allAclsData, isLoading } = useQuery(listACLs, {});
6258
const roleMembers = useStore(useRolesStore, (s) => s.roleMembers);
6359

6460
const permissions = useMemo(() => {
@@ -111,7 +107,7 @@ export function usePrincipalPermissions() {
111107
isLoading: isAclsLoading,
112108
isError: isAclsError,
113109
error: aclsError,
114-
} = useQuery(listACLs, {} as ListACLsRequest);
110+
} = useQuery(listACLs, {});
115111

116112
const { principals, isUsersError, usersError } = usePrincipalList();
117113
const roleMembers = useStore(useRolesStore, (s) => s.roleMembers);

frontend/src/components/pages/security/shared/user-role-tags.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { useQuery } from '@connectrpc/connect-query';
1313
import { useNavigate } from '@tanstack/react-router';
1414
import { TagsValue } from 'components/redpanda-ui/components/tags';
1515

16-
import type { ListACLsRequest } from '../../../../protogen/redpanda/api/dataplane/v1/acl_pb';
1716
import { listACLs } from '../../../../protogen/redpanda/api/dataplane/v1/acl-ACLService_connectquery';
1817
import { rolesApi } from '../../../../state/backend-api';
1918
import { useSupportedFeaturesStore } from '../../../../state/supported-features';
@@ -43,7 +42,7 @@ export const UserRoleTags = ({
4342
filter: {
4443
principal: `${principalType}:${userName}`,
4544
},
46-
} as ListACLsRequest,
45+
},
4746
{
4847
enabled: !!userName,
4948
select: (response) => response.resources.length > 0,

frontend/src/components/pages/topics/tab-docu.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ const allowedProtocols = ['http://', 'https://', 'mailto://'];
4242

4343
function sanitizeUrl(uri: string): string {
4444
const baseTransformed = baseUriTransformer(uri);
45-
// biome-ignore lint/suspicious/noConsole: intentional console usage
46-
console.log('baseTransformed', baseTransformed);
4745
if (baseTransformed !== uri) {
4846
return baseTransformed;
4947
}

frontend/src/federation/console-app.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { createConnectTransport } from '@connectrpc/connect-web';
3535
import { QueryClient } from '@tanstack/react-query';
3636
import { createMemoryHistory, createRouter, RouterProvider } from '@tanstack/react-router';
3737
import { protobufRegistry } from 'protobuf-registry';
38+
import { LONG_LIVED_CACHE_STALE_TIME } from 'react-query/react-query.utils';
3839

3940
import { FederatedProviders } from './federated-providers';
4041
import { TokenManager } from './token-manager';
@@ -139,7 +140,7 @@ function createFederatedQueryClient() {
139140
return new QueryClient({
140141
defaultOptions: {
141142
queries: {
142-
staleTime: 1000 * 60 * 5, // 5 minutes
143+
staleTime: LONG_LIVED_CACHE_STALE_TIME,
143144
retry: 1,
144145
},
145146
},

frontend/src/query-client.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Code, ConnectError } from '@connectrpc/connect';
22
import { QueryClient } from '@tanstack/react-query';
3+
import { DEFAULT_CACHE_STALE_TIME } from 'react-query/react-query.utils';
34

45
function isConnectError(error: Error | ConnectError): error is ConnectError {
56
return error instanceof ConnectError;
@@ -8,7 +9,7 @@ function isConnectError(error: Error | ConnectError): error is ConnectError {
89
const queryClient = new QueryClient({
910
defaultOptions: {
1011
queries: {
11-
staleTime: 3 * 1000, // 3 seconds
12+
staleTime: DEFAULT_CACHE_STALE_TIME,
1213
retry: (failureCount, error) => {
1314
if (failureCount > 3) {
1415
return false;

0 commit comments

Comments
 (0)