Skip to content

Commit 0a21717

Browse files
committed
feat: connect tiles is now prop driven via list component schema endpoint, better progressive loading states, no more silent errors, better conditional rendering of new UI withini legacy entry point
1 parent ef668e0 commit 0a21717

File tree

9 files changed

+220
-47
lines changed

9 files changed

+220
-47
lines changed

frontend/src/components/pages/connect/overview.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
TaskState,
3030
TasksColumn,
3131
} from './helper';
32-
import { isServerless } from '../../../config';
32+
import { isEmbedded, isFeatureFlagEnabled, isServerless } from '../../../config';
3333
import { ListSecretScopesRequestSchema } from '../../../protogen/redpanda/api/dataplane/v1/secret_pb';
3434
import { appGlobal } from '../../../state/app-global';
3535
import { api, rpcnSecretManagerApi } from '../../../state/backend-api';
@@ -42,6 +42,7 @@ import SearchBar from '../../misc/search-bar';
4242
import Section from '../../misc/section';
4343
import Tabs, { type Tab } from '../../misc/tabs/tabs';
4444
import { PageComponent, type PageInitHelper } from '../page';
45+
import { PipelineListPage } from '../rp-connect/pipeline/list';
4546
import RpConnectPipelinesList from '../rp-connect/pipelines-list';
4647
import { RedpandaConnectIntro } from '../rp-connect/redpanda-connect-intro';
4748

@@ -84,17 +85,24 @@ const WrapKafkaConnectOverview: FunctionComponent<{ matchedPath: string }> = (pr
8485

8586
const { data: kafkaConnectors, isLoading: isLoadingKafkaConnectors } = useKafkaConnectConnectorsQuery();
8687

87-
if (isLoadingKafkaConnectors) {
88-
return <WaitingRedpanda />;
89-
}
90-
91-
const isKafkaConnectEnabled = kafkaConnectors?.isConfigured ?? false;
88+
const isKafkaConnectEnabled = kafkaConnectors?.isConfigured === true;
9289

93-
return <KafkaConnectOverview defaultView={defaultTab} isKafkaConnectEnabled={isKafkaConnectEnabled} {...props} />;
90+
return (
91+
<KafkaConnectOverview
92+
defaultView={defaultTab}
93+
isKafkaConnectEnabled={isKafkaConnectEnabled}
94+
isLoadingKafkaConnectors={isLoadingKafkaConnectors}
95+
{...props}
96+
/>
97+
);
9498
};
9599

96100
@observer
97-
class KafkaConnectOverview extends PageComponent<{ defaultView: string; isKafkaConnectEnabled: boolean }> {
101+
class KafkaConnectOverview extends PageComponent<{
102+
defaultView: string;
103+
isKafkaConnectEnabled: boolean;
104+
isLoadingKafkaConnectors: boolean;
105+
}> {
98106
initPage(p: PageInitHelper): void {
99107
p.title = 'Overview';
100108
p.addBreadcrumb('Connect', '/connect-clusters');
@@ -122,6 +130,12 @@ class KafkaConnectOverview extends PageComponent<{ defaultView: string; isKafkaC
122130
}
123131

124132
render() {
133+
if (isFeatureFlagEnabled('enableRpcnTiles') && isEmbedded()) {
134+
return <PipelineListPage />;
135+
}
136+
if (this.props.isLoadingKafkaConnectors) {
137+
return <WaitingRedpanda />;
138+
}
125139
const tabs = [
126140
{
127141
key: ConnectView.RedpandaConnect,
@@ -422,7 +436,7 @@ class TabTasks extends Component {
422436
}
423437

424438
// biome-ignore lint/complexity/noBannedTypes: empty object represents pages with no route params
425-
const TabKafkaConnect = observer((_p: {}) => {
439+
export const TabKafkaConnect = observer((_p: {}) => {
426440
const settings = uiSettings.kafkaConnect;
427441

428442
if (api.connectConnectorsError) {

frontend/src/components/pages/rp-connect/onboarding/add-connector-dialog.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
DialogHeader,
77
DialogTitle,
88
} from 'components/redpanda-ui/components/dialog';
9+
import type { ComponentList } from 'protogen/redpanda/api/dataplane/v1/pipeline_pb';
910

1011
import { ConnectTiles } from './connect-tiles';
1112
import type { ConnectComponentType } from '../types/schema';
@@ -15,11 +16,13 @@ export const AddConnectorDialog = ({
1516
onCloseAddConnector,
1617
connectorType,
1718
onAddConnector,
19+
components,
1820
}: {
1921
isOpen: boolean;
2022
onCloseAddConnector: () => void;
2123
connectorType?: ConnectComponentType;
2224
onAddConnector: ((connectionName: string, connectionType: ConnectComponentType) => void) | undefined;
25+
components: ComponentList;
2326
}) => (
2427
<Dialog onOpenChange={onCloseAddConnector} open={isOpen}>
2528
<DialogContent size="xl">
@@ -30,6 +33,7 @@ export const AddConnectorDialog = ({
3033
<DialogBody>
3134
<ConnectTiles
3235
className="px-0 pt-0"
36+
components={components}
3337
componentTypeFilter={connectorType ? [connectorType] : undefined}
3438
gridCols={3}
3539
hideHeader

frontend/src/components/pages/rp-connect/onboarding/connect-tiles.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import { Heading, Link, Text } from 'components/redpanda-ui/components/typograph
1818
import { cn } from 'components/redpanda-ui/lib/utils';
1919
import { SearchIcon } from 'lucide-react';
2020
import type { MotionProps } from 'motion/react';
21+
import type { ComponentList } from 'protogen/redpanda/api/dataplane/v1/pipeline_pb';
2122
import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
2223
import { useForm } from 'react-hook-form';
23-
import { useListComponentsQuery } from 'react-query/api/connect';
2424

2525
import { ConnectTile } from './connect-tile';
2626
import type { ConnectComponentSpec, ConnectComponentType, ExtendedConnectComponentSpec } from '../types/schema';
@@ -151,6 +151,8 @@ const ConnectTilesSkeleton = memo(
151151
ConnectTilesSkeleton.displayName = 'ConnectTilesSkeleton';
152152

153153
export type ConnectTilesProps = {
154+
components?: ComponentList;
155+
isLoading?: boolean;
154156
additionalComponents?: ExtendedConnectComponentSpec[];
155157
componentTypeFilter?: ConnectComponentType[];
156158
onChange?: (connectionName: string, connectionType: ConnectComponentType) => void;
@@ -172,6 +174,8 @@ export const ConnectTiles = memo(
172174
forwardRef<BaseStepRef<ConnectTilesListFormData>, ConnectTilesProps & MotionProps>(
173175
(
174176
{
177+
components,
178+
isLoading,
175179
additionalComponents,
176180
componentTypeFilter,
177181
onChange,
@@ -224,11 +228,7 @@ export const ConnectTiles = memo(
224228
defaultValues,
225229
});
226230

227-
const { data: componentListResponse, isLoading: isLoadingComponents } = useListComponentsQuery();
228-
const builtInComponents = useMemo(
229-
() => (componentListResponse?.components ? parseSchema(componentListResponse.components) : []),
230-
[componentListResponse]
231-
);
231+
const builtInComponents = useMemo(() => (components ? parseSchema(components) : []), [components]);
232232
const allComponents = useMemo(
233233
() => [...builtInComponents, ...(additionalComponents || [])],
234234
[builtInComponents, additionalComponents]
@@ -384,9 +384,10 @@ export const ConnectTiles = memo(
384384
);
385385
});
386386

387-
const hasNoResults = !isLoadingComponents && filteredComponents.length === 0;
388387
const hasResults = filteredComponents.length > 0;
389-
const showSkeleton = hasResults && isLoadingComponents;
388+
const showSkeleton = isLoading;
389+
// biome-ignore lint/complexity/useSimplifiedLogicExpression: Logic is intentionally explicit for clarity
390+
const hasNoResults = !showSkeleton && !hasResults;
390391

391392
let content: React.ReactNode;
392393

frontend/src/components/pages/rp-connect/onboarding/create-pipeline-sidebar.tsx

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import { useDisclosure } from '@redpanda-data/ui';
2+
import { Skeleton, SkeletonGroup } from 'components/redpanda-ui/components/skeleton';
23
import { cn } from 'components/redpanda-ui/lib/utils';
34
import type { editor } from 'monaco-editor';
5+
import type { ComponentList } from 'protogen/redpanda/api/dataplane/v1/pipeline_pb';
46
import { memo, useCallback, useMemo, useState } from 'react';
57
import { useOnboardingWizardDataStore } from 'state/onboarding-wizard-store';
68

79
import { AddConnectorDialog } from './add-connector-dialog';
810
import { AddConnectorsCard } from './add-connectors-card';
911
import { AddContextualVariablesCard } from './add-contextual-variables-card';
1012
import { AddSecretsCard } from './add-secrets-card';
11-
import type { ConnectComponentSpec, ConnectComponentType } from '../types/schema';
13+
import type { ConnectComponentType } from '../types/schema';
14+
import { parseSchema } from '../utils/schema';
1215
import { getConnectTemplate } from '../utils/yaml';
1316

1417
const sidebarClassNames = 'w-[260px]';
@@ -17,13 +20,21 @@ type CreatePipelineSidebarProps = {
1720
editorInstance: editor.IStandaloneCodeEditor | null;
1821
editorContent: string;
1922
setYamlContent: (yaml: string) => void;
20-
components: ConnectComponentSpec[];
23+
componentList?: ComponentList;
24+
isComponentListLoading?: boolean;
2125
};
2226

2327
export const CreatePipelineSidebar = memo(
24-
({ editorInstance, editorContent, setYamlContent, components }: CreatePipelineSidebarProps) => {
28+
({
29+
editorInstance,
30+
editorContent,
31+
setYamlContent,
32+
componentList: rawComponentList,
33+
isComponentListLoading,
34+
}: CreatePipelineSidebarProps) => {
2535
const { isOpen: isAddConnectorOpen, onOpen: openAddConnector, onClose: closeAddConnector } = useDisclosure();
2636
const [selectedConnector, setSelectedConnector] = useState<ConnectComponentType | undefined>(undefined);
37+
const components = useMemo(() => (rawComponentList ? parseSchema(rawComponentList) : []), [rawComponentList]);
2738

2839
const hasInput = useMemo(() => editorContent.includes('input:'), [editorContent]);
2940
const hasOutput = useMemo(() => editorContent.includes('output:'), [editorContent]);
@@ -64,6 +75,17 @@ export const CreatePipelineSidebar = memo(
6475
openAddConnector();
6576
};
6677

78+
if (isComponentListLoading) {
79+
return (
80+
<div className={cn(sidebarClassNames, 'flex flex-col gap-4')}>
81+
<SkeletonGroup direction="vertical" spacing="default">
82+
<Skeleton variant="heading" width="full" />
83+
<Skeleton className="h-10 w-full" />
84+
</SkeletonGroup>
85+
</div>
86+
);
87+
}
88+
6789
return (
6890
<div className={cn(sidebarClassNames, 'flex flex-col gap-4')}>
6991
<AddConnectorsCard
@@ -75,12 +97,15 @@ export const CreatePipelineSidebar = memo(
7597
<AddSecretsCard editorContent={editorContent} editorInstance={editorInstance} />
7698
<AddContextualVariablesCard editorContent={editorContent} editorInstance={editorInstance} />
7799

78-
<AddConnectorDialog
79-
connectorType={selectedConnector}
80-
isOpen={isAddConnectorOpen}
81-
onAddConnector={handleAddConnector}
82-
onCloseAddConnector={closeAddConnector}
83-
/>
100+
{rawComponentList && (
101+
<AddConnectorDialog
102+
components={rawComponentList}
103+
connectorType={selectedConnector}
104+
isOpen={isAddConnectorOpen}
105+
onAddConnector={handleAddConnector}
106+
onCloseAddConnector={closeAddConnector}
107+
/>
108+
)}
84109
</div>
85110
);
86111
}

frontend/src/components/pages/rp-connect/onboarding/onboarding-wizard.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const ConnectOnboardingWizard = ({
6565
}: ConnectOnboardingWizardProps = {}) => {
6666
const navigate = useNavigate();
6767

68-
const { data: componentListResponse } = useListComponentsQuery();
68+
const { data: componentListResponse, isLoading: isComponentListLoading } = useListComponentsQuery();
6969
const components = useMemo(
7070
() => (componentListResponse?.components ? parseSchema(componentListResponse.components) : []),
7171
[componentListResponse]
@@ -362,6 +362,8 @@ export const ConnectOnboardingWizard = ({
362362
{methods.switch({
363363
[WizardStep.ADD_INPUT]: () => (
364364
<ConnectTiles
365+
components={componentListResponse?.components}
366+
isLoading={isComponentListLoading}
365367
{...stepMotionProps}
366368
additionalComponents={additionalComponents}
367369
componentTypeFilter={['input', 'custom']}
@@ -376,6 +378,8 @@ export const ConnectOnboardingWizard = ({
376378
),
377379
[WizardStep.ADD_OUTPUT]: () => (
378380
<ConnectTiles
381+
components={componentListResponse?.components}
382+
isLoading={isComponentListLoading}
379383
{...stepMotionProps}
380384
additionalComponents={additionalComponents}
381385
componentTypeFilter={['output', 'custom']}

frontend/src/components/pages/rp-connect/pipeline/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ export default function PipelinePage() {
203203

204204
const pipeline = useMemo(() => pipelineResponse?.response?.pipeline, [pipelineResponse]);
205205

206-
const { data: componentListResponse } = useListComponentsQuery();
206+
const { data: componentListResponse, isLoading: isComponentListLoading } = useListComponentsQuery();
207207

208208
const components = useMemo(
209209
() => (componentListResponse?.components ? parseSchema(componentListResponse.components) : []),
@@ -495,9 +495,10 @@ export default function PipelinePage() {
495495
</div>
496496
{(mode === 'create' || mode === 'edit') && (
497497
<CreatePipelineSidebar
498-
components={components}
498+
componentList={componentListResponse?.components}
499499
editorContent={yamlContent}
500500
editorInstance={editorInstance}
501+
isComponentListLoading={isComponentListLoading}
501502
setYamlContent={handleSetYamlContent}
502503
/>
503504
)}

0 commit comments

Comments
 (0)