Skip to content

Commit

Permalink
Remove charts and visual details that will not be available for mvp (s…
Browse files Browse the repository at this point in the history
  • Loading branch information
riccardo-forina authored Oct 3, 2023
1 parent 19c3ff7 commit 1579b16
Show file tree
Hide file tree
Showing 34 changed files with 553 additions and 427 deletions.
42 changes: 42 additions & 0 deletions ui/api/kafka.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
ClusterDetail,
ClusterList,
ClusterResponse,
ClustersResponse,
} from "@/api/types";

export async function getKafkaClusters(): Promise<ClusterList[]> {
const url = `${process.env.BACKEND_URL}/api/kafkas?fields%5Bkafkas%5D=name,bootstrapServers,authType`;
try {
const res = await fetch(url, {
headers: {
Accept: "application/json",
},
cache: "no-store",
});
const rawData = await res.json();
return ClustersResponse.parse(rawData).data;
} catch (err) {
console.error(err);
throw err;
}
}

export async function getKafkaCluster(
clusterId: string,
): Promise<ClusterDetail> {
const url = `${process.env.BACKEND_URL}/api/kafkas/${clusterId}/?fields%5Bkafkas%5D=name,namespace,creationTimestamp,nodes,controller,authorizedOperations,bootstrapServers,authType`;
try {
const res = await fetch(url, {
headers: {
Accept: "application/json",
},
cache: "no-store",
});
const rawData = await res.json();
return ClusterResponse.parse(rawData).data;
} catch (err) {
console.error(err);
throw err;
}
}
40 changes: 19 additions & 21 deletions ui/api/resources.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use server";
import { getKafkaClusters } from "@/api/kafka";
import {
Cluster,
ClusterList,
KafkaResource,
RegistryResource,
Resource,
ResourceTypeKafka,
ResourceTypeRegistry,
Response,
} from "@/api/types";
import { getSession, setSession } from "@/utils/session";

Expand All @@ -22,7 +22,21 @@ export async function getResources(scope: unknown): Promise<unknown> {
const { resources } = await getSession("resources");
switch (scope) {
case "kafka":
return resources.filter((b) => b.type === "kafka");
return [
...(await getKafkaClusters()).map<KafkaResource>((c) => ({
id: c.id,
type: "kafka",
attributes: {
name: c.attributes.name,
cluster: c,
source: "auto",
bootstrapServer: c.attributes.bootstrapServers,
principal: "automatic",
mechanism: "automatic",
},
})),
...resources.filter((b) => b.type === "kafka"),
];
case "registry":
return resources.filter((b) => b.type === "registry");
}
Expand Down Expand Up @@ -69,7 +83,7 @@ export async function createKafkaResource({
bootstrapServer: string;
principal: string;
name: string;
cluster: Cluster | undefined;
cluster: ClusterList | undefined;
}) {
const session = await getSession("resources");
const resources = (session?.resources || []) as Resource[];
Expand All @@ -82,6 +96,7 @@ export async function createKafkaResource({
name,
bootstrapServer,
principal,
source: "user",
},
};
const newAuthProfiles = [...resources, newProfile];
Expand All @@ -91,20 +106,3 @@ export async function createKafkaResource({
});
return newProfile;
}

export async function getClusters(): Promise<Cluster[]> {
const url = `${process.env.BACKEND_URL}/api/kafkas?fields%5Bkafkas%5D=name,bootstrapServers,authType`;
try {
const res = await fetch(url, {
headers: {
Accept: "application/json",
},
cache: "no-store",
});
const rawData = await res.json();
return Response.parse(rawData).data;
} catch (err) {
console.error(err);
throw err;
}
}
37 changes: 32 additions & 5 deletions ui/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
import { z } from "zod";

const ClusterSchema = z.object({
const ClusterListSchema = z.object({
id: z.string(),
type: z.string(),
attributes: z.object({
name: z.string(),
bootstrapServers: z.string(),
}),
});
export const Response = z.object({
data: z.array(ClusterSchema),
export const ClustersResponse = z.object({
data: z.array(ClusterListSchema),
});
export type Cluster = z.infer<typeof ClusterSchema>;
export type ClusterList = z.infer<typeof ClusterListSchema>;

const NodeSchema = z.object({
id: z.number(),
host: z.string(),
port: z.number(),
rack: z.string().optional(),
});
export type KafkaNode = z.infer<typeof NodeSchema>;
const ClusterDetailSchema = z.object({
id: z.string(),
type: z.string(),
attributes: z.object({
name: z.string(),
namespace: z.string(),
creationTimestamp: z.string(),
nodes: z.array(NodeSchema),
controller: NodeSchema,
authorizedOperations: z.array(z.string()),
bootstrapServers: z.string(),
authType: z.string(),
}),
});
export const ClusterResponse = z.object({
data: ClusterDetailSchema,
});
export type ClusterDetail = z.infer<typeof ClusterDetailSchema>;

export const ResourceTypeRegistry = "registry" as const;
export const ResourceTypeKafka = "kafka" as const;
Expand All @@ -22,8 +48,9 @@ export const KafkaResourceSchema = z.object({
name: z.string(),
bootstrapServer: z.string(),
principal: z.string(),
cluster: ClusterSchema.optional(),
cluster: ClusterListSchema.optional(),
mechanism: z.string(),
source: z.union([z.literal("user"), z.literal("auto")]),
}),
});
export type KafkaResource = z.infer<typeof KafkaResourceSchema>;
Expand Down
88 changes: 88 additions & 0 deletions ui/app/[locale]/kafka/ClustersTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"use client";

import { KafkaResource } from "@/api/types";
import { ResponsiveTable } from "@/components/table";
import { ClipboardCopy, Label, LabelGroup } from "@patternfly/react-core";
import {
DataSourceIcon,
SecurityIcon,
UserIcon,
} from "@patternfly/react-icons";
import Link from "next/link";

const columns = ["name", "source", "bootstrapUrl", "authentication"] as const;

export function ClustersTable({
clusters = [],
}: {
clusters: KafkaResource[] | undefined;
}) {
return (
<ResponsiveTable
ariaLabel={"Kafka clusters"}
columns={columns}
data={clusters}
renderHeader={({ column, Th }) => {
switch (column) {
case "name":
return <Th width={15}>Name</Th>;
case "bootstrapUrl":
return <Th>Bootstrap url</Th>;
case "source":
return <Th>Source</Th>;
case "authentication":
return <Th width={15}>Authentication</Th>;
}
}}
renderCell={({ column, row, Td }) => {
switch (column) {
case "name":
return (
<Td>
<Link href={`/kafka/${row.id}`}>{row.attributes.name}</Link>
</Td>
);
case "bootstrapUrl":
return (
<Td>
<ClipboardCopy
hoverTip="Copy"
clickTip="Copied"
variant="inline-compact"
>
{row.attributes.bootstrapServer}
</ClipboardCopy>
</Td>
);
case "source":
return (
<Td>
<Label icon={<DataSourceIcon />} color={"blue"}>
{row.attributes.source === "auto" ? "Autodiscovery" : "User"}
</Label>
</Td>
);
case "authentication":
return (
<Td>
{row.attributes.source === "auto" ? (
<Label icon={<SecurityIcon />} color={"purple"}>
Automatic
</Label>
) : (
<LabelGroup>
<Label icon={<SecurityIcon />} color={"purple"}>
{row.attributes.mechanism}
</Label>
<Label icon={<UserIcon />} color={"gold"}>
{row.attributes.principal}
</Label>
</LabelGroup>
)}
</Td>
);
}
}}
/>
);
}
16 changes: 0 additions & 16 deletions ui/app/[locale]/kafka/[...anyKafka]/route.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function BrokersActiveBreadcrumb() {
return "Brokers";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function ConsumerGroupsActiveBreadcrumb() {
return "Consumer groups";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function SchemaRegistryActiveBreadcrumb() {
return "Schema registry";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function TopicsActiveBreadcrumb() {
return "Topics";
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use client";
import { KafkaResource } from "@/api/types";
import { ClusterDetail, KafkaResource } from "@/api/types";
import {
Divider,
Dropdown,
Expand All @@ -18,7 +18,7 @@ export const KafkaSelectorBreadcrumbItem = ({
clusters,
isActive = false,
}: {
selected: KafkaResource;
selected: ClusterDetail;
clusters: KafkaResource[];
isActive?: boolean;
}) => {
Expand All @@ -33,7 +33,7 @@ export const KafkaSelectorBreadcrumbItem = ({
const resourceToDropdownItem = (b: KafkaResource) => (
<DropdownItem
key={b.id}
value={b.id}
value={b.attributes.cluster?.id}
id={b.id}
onClick={() => {
setIsOpen(false);
Expand Down
65 changes: 65 additions & 0 deletions ui/app/[locale]/kafka/[kafkaId]/(root)/brokers/BrokersTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"use client";

import { KafkaNode } from "@/api/types";
import { ResponsiveTable } from "@/components/table";
import { ClipboardCopy, Label, LabelGroup } from "@patternfly/react-core";
import { ServerIcon } from "@patternfly/react-icons";

const columns = ["id", "host", "rack"] as const;

export function BrokersTable({
brokers,
controller,
}: {
brokers: KafkaNode[];
controller: KafkaNode;
}) {
return (
<ResponsiveTable
ariaLabel={"Kafka clusters"}
columns={columns}
data={brokers}
renderHeader={({ column, Th }) => {
switch (column) {
case "id":
return <Th width={15}>Id</Th>;
case "host":
return <Th>Host</Th>;
case "rack":
return <Th>Rack</Th>;
}
}}
renderCell={({ column, row, Td }) => {
switch (column) {
case "id":
return (
<Td>
<LabelGroup>
<Label icon={<ServerIcon />} color={"orange"}>
{row.id}
</Label>
{row.id === controller.id && (
<Label color={"purple"}>Controller</Label>
)}
</LabelGroup>
</Td>
);
case "host":
return (
<Td>
<ClipboardCopy
hoverTip="Copy"
clickTip="Copied"
variant="inline-compact"
>
{row.host}:{row.port}
</ClipboardCopy>
</Td>
);
case "rack":
return <Td>{row.rack || "-"}</Td>;
}
}}
/>
);
}
Loading

0 comments on commit 1579b16

Please sign in to comment.