diff --git a/src/pages/consumer-groups/consumer-group.tsx b/src/pages/consumer-groups/consumer-group.tsx index ec89989f..3a4896ce 100644 --- a/src/pages/consumer-groups/consumer-group.tsx +++ b/src/pages/consumer-groups/consumer-group.tsx @@ -1,16 +1,58 @@ -import { Text, Button, Container, Divider, Group, Stack, Grid, Center, Loader } from "@mantine/core"; -import { IconRefresh } from "@tabler/icons"; +import { Text, Button, Container, Divider, Group, Stack, Grid, Center, Loader, Menu } from "@mantine/core"; +import { useSetState } from "@mantine/hooks"; +import { openConfirmModal } from "@mantine/modals"; +import { IconFlag, IconPlayerPlay, IconRefresh, IconTool } from "@tabler/icons"; import { useQuery } from "@tanstack/react-query"; import { PageHeader } from "../../components"; -import { describeConsumerGroup } from "../../tauri/admin"; +import { ConsumerSettingsFrom } from "../../models"; +import { describeConsumerGroup, setConsumerGroup } from "../../tauri/admin"; export const ConsumerGroup = ({ name, clusterId }: { name: string; clusterId: string }) => { + const [state, setState] = useSetState<{ isResetting: boolean }>({ isResetting: false }); const { isLoading, data, refetch, isRefetching } = useQuery( ["describeConsumerGroup", clusterId, name], () => describeConsumerGroup(clusterId, name), { refetchOnWindowFocus: false, refetchOnMount: false } ); + const resetOffset = (offset: ConsumerSettingsFrom) => { + if (data) { + openConfirmModal({ + title: "Reset offset", + children: ( + <> + + Are you sure to reset the offset of the consumer group{" "} + + {data.name} + {" "} + to{" "} + + {offset.toString()} + + ? + + + This action is irreversible. + + + ), + labels: { confirm: "Confirm", cancel: "Cancel" }, + onCancel: () => console.log("Cancel"), + onConfirm: async () => { + setState({ isResetting: true }); + await setConsumerGroup( + clusterId, + data.name, + data.offsets.map((o) => o.topic), + offset + ).then((_) => refetch()); + setState({ isResetting: false }); + }, + }); + } + }; + return ( @@ -22,20 +64,22 @@ export const ConsumerGroup = ({ name, clusterId }: { name: string; clusterId: st Refresh - {/* - todo: allow reset each single topic/partition - + - - }>Reset to the beginning - }>Reset to end - }>Reset to a point in time + resetOffset("Beginning")} icon={}> + Reset to the beginning + + resetOffset("End")} icon={}> + Reset to end + + {/* }>Reset to a point in time */} - */} + {isLoading && (
diff --git a/src/pages/consumer-groups/consumer-groups-list.tsx b/src/pages/consumer-groups/consumer-groups-list.tsx index 8aa7a4ea..a7a61918 100644 --- a/src/pages/consumer-groups/consumer-groups-list.tsx +++ b/src/pages/consumer-groups/consumer-groups-list.tsx @@ -1,8 +1,9 @@ -import { ActionIcon, Button, Center, Group, Modal, Select, Stack, Text, TextInput, Title } from "@mantine/core"; +import { ActionIcon, Button, Center, Chip, Group, Modal, Select, Stack, Text, TextInput, Title } from "@mantine/core"; import { IconTrash } from "@tabler/icons"; import { useQuery } from "@tanstack/react-query"; import { useState } from "react"; import { SingleLineTitle } from "../../components"; +import { ConsumerSettingsFrom } from "../../models"; import { setConsumerGroup, getConsumerGroups, listTopics } from "../../tauri/admin"; import { ItemList } from "../common"; @@ -44,7 +45,11 @@ export const ConsumerGroupsList = (props: SchemaListProps) => { const CreateConsumerGroupModal = ({ clusterId, close }: { clusterId: string; close: () => void }) => { const { data } = useQuery(["listTopics", clusterId], () => listTopics(clusterId)); - const [state, setState] = useState<{ name: string; topics: string[] }>({ name: "", topics: [] }); + const [state, setState] = useState<{ name: string; topics: string[]; offset: string }>({ + name: "", + topics: [], + offset: "Beginning", + }); return ( @@ -53,7 +58,20 @@ const CreateConsumerGroupModal = ({ clusterId, close }: { clusterId: string; clo value={state.name} onChange={(event) => setState((s) => ({ ...s, name: event.currentTarget.value }))} label="Consumer group name"> + + Set offset + + setState((s) => ({ ...s, offset: v }))} + value={state.offset}> + End + Beginning + {/* Custom Time */} +