Skip to content

Commit

Permalink
Merge pull request #100 from cptKNJO/ui
Browse files Browse the repository at this point in the history
Add dropdown menu to each row
  • Loading branch information
uroni committed Jun 9, 2024
2 parents c4931a4 + 821483e commit ce24e21
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 13 deletions.
77 changes: 77 additions & 0 deletions urbackupserver/www2/src/components/StatusRowMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {
Menu,
MenuButton,
MenuItem,
MenuList,
MenuPopover,
MenuTrigger,
} from "@fluentui/react-components";
import { MouseEvent } from "react";
import { MoreHorizontal24Filled } from "@fluentui/react-icons";
import { useMutation, useQueryClient } from "react-query";

import { urbackupServer } from "../App";
import { BackupType, StatusClientItem } from "../api/urbackupserver";

export function StatusRowMenu({ id }: { id: StatusClientItem["id"] }) {
const queryClient = useQueryClient();

const removeClientMutation = useMutation(urbackupServer.removeClient, {
onSuccess: () => {
queryClient.invalidateQueries("status");
},
});

const startBackupMutation = useMutation(
({
id,
type,
}: {
id: Parameters<typeof urbackupServer.startBackup>["0"];
type: Parameters<typeof urbackupServer.startBackup>["1"];
}) => urbackupServer.startBackup(id, type),
);

const removeClient = () => {
removeClientMutation.mutate(id);
};

const startBackup = (e: MouseEvent<HTMLDivElement>) => {
const type = e.currentTarget.dataset.type;

if (type) {
startBackupMutation.mutate({ id: [id], type: +type });
}
};

return (
<Menu>
<MenuTrigger disableButtonEnhancement>
<MenuButton
appearance="transparent"
aria-label="More"
icon={<MoreHorizontal24Filled />}
onClick={(e) => e.stopPropagation()}
/>
</MenuTrigger>

<MenuPopover onClick={(e) => e.stopPropagation()}>
<MenuList>
<MenuItem data-type={BackupType.INCR_FILE} onClick={startBackup}>
Incremental file backup
</MenuItem>
<MenuItem data-type={BackupType.FULL_FILE} onClick={startBackup}>
Full file backup
</MenuItem>
<MenuItem data-type={BackupType.INCR_IMAGE} onClick={startBackup}>
Incremental image backup
</MenuItem>
<MenuItem data-type={BackupType.FULL_IMAGE} onClick={startBackup}>
Full image backup
</MenuItem>
<MenuItem onClick={removeClient}>Remove client</MenuItem>
</MenuList>
</MenuPopover>
</Menu>
);
}
38 changes: 25 additions & 13 deletions urbackupserver/www2/src/pages/Status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,20 @@ import { urbackupServer } from "../App";
import { chunk } from "../utils/chunk";
import { registerIcons } from "@fluentui/react-experiments/lib/Styling";
import {
ArrowNext20Regular,
ArrowPrevious20Regular,
ChevronLeft20Regular,
ChevronRight20Regular,
ArrowNext20Filled,
ArrowPrevious20Filled,
ChevronLeft20Filled,
ChevronRight20Filled,
} from "@fluentui/react-icons";
import { StatusRowMenu } from "../components/StatusRowMenu";

// Register icons used in Pagination @fluentui/react-experiments. See https://github.com/microsoft/fluentui/wiki/Using-icons#registering-custom-icons.
registerIcons({
icons: {
CaretSolidLeft: <ChevronLeft20Regular />,
CaretSolidRight: <ChevronRight20Regular />,
Next: <ArrowNext20Regular />,
Previous: <ArrowPrevious20Regular />,
CaretSolidLeft: <ChevronLeft20Filled />,
CaretSolidRight: <ChevronRight20Filled />,
Next: <ArrowNext20Filled />,
Previous: <ArrowPrevious20Filled />,
},
});

Expand Down Expand Up @@ -98,6 +99,13 @@ const columns: TableColumnDefinition<StatusClientItem>[] = [
);
},
}),
createTableColumn<StatusClientItem>({
columnId: "action",
renderHeaderCell: () => {
return "Actions";
},
renderCell: ({ id }) => <StatusRowMenu id={id} />,
}),
];

const useStyles = makeStyles({
Expand Down Expand Up @@ -132,7 +140,11 @@ const Status = () => {
const classes = useStyles();

const dataItems = statusResult.data!.status;
const pageData = chunk(dataItems, pageSize);

// Hide items with delete_pending === 1
const filteredItems = dataItems.filter((d) => d.delete_pending !== "1");

const pageData = chunk(filteredItems, pageSize);

return (
<>
Expand All @@ -145,8 +157,8 @@ const Status = () => {
defaultValue={pageSize}
onChange={(_, data) => setPageSize(+data.value)}
>
{PAGE_SIZES.map((size) => (
<option>{size}</option>
{PAGE_SIZES.map((size, id) => (
<option key={id}>{size}</option>
))}
</Select>
entries
Expand All @@ -167,9 +179,9 @@ const Status = () => {
</DataGridRow>
</DataGridHeader>
<DataGridBody<StatusClientItem>>
{({ item, rowId }) => (
{({ item }) => (
<DataGridRow<StatusClientItem>
key={rowId}
key={item.id}
selectionCell={{ "aria-label": "Select row" }}
>
{({ renderCell }) => (
Expand Down

0 comments on commit ce24e21

Please sign in to comment.