diff --git a/src/modules/activity/ActivityDescription.tsx b/src/modules/activity/ActivityDescription.tsx
index f845dbd..1838ba9 100644
--- a/src/modules/activity/ActivityDescription.tsx
+++ b/src/modules/activity/ActivityDescription.tsx
@@ -47,6 +47,14 @@ export default function ActivityDescription({ event }: Props) {
);
+ if (event.activity_code == "setupkey.delete")
+ return (
+
+ Setup-Key {m.name} with key {m.key} was
+ deleted
+
+ );
+
if (event.activity_code == "setupkey.add")
return (
diff --git a/src/modules/common-table-rows/EmptyRow.tsx b/src/modules/common-table-rows/EmptyRow.tsx
index 260fb8e..e561727 100644
--- a/src/modules/common-table-rows/EmptyRow.tsx
+++ b/src/modules/common-table-rows/EmptyRow.tsx
@@ -1,3 +1,9 @@
-export default function EmptyRow() {
- return
-
;
+import { cn } from "@utils/helpers";
+
+type Props = {
+ className?: string;
+};
+
+export default function EmptyRow({ className }: Readonly
) {
+ return -
;
}
diff --git a/src/modules/setup-keys/SetupKeyActionCell.tsx b/src/modules/setup-keys/SetupKeyActionCell.tsx
index da9ccbe..cc213eb 100644
--- a/src/modules/setup-keys/SetupKeyActionCell.tsx
+++ b/src/modules/setup-keys/SetupKeyActionCell.tsx
@@ -1,7 +1,7 @@
import Button from "@components/Button";
import { notify } from "@components/Notification";
import { useApiCall } from "@utils/api";
-import { Trash2 } from "lucide-react";
+import { Trash2, Undo2Icon } from "lucide-react";
import * as React from "react";
import { useSWRConfig } from "swr";
import { useDialog } from "@/contexts/DialogProvider";
@@ -10,16 +10,26 @@ import { SetupKey } from "@/interfaces/SetupKey";
type Props = {
setupKey: SetupKey;
};
-export default function SetupKeyActionCell({ setupKey }: Props) {
+export default function SetupKeyActionCell({ setupKey }: Readonly) {
const { confirm } = useDialog();
- const deleteRequest = useApiCall("/setup-keys/" + setupKey.id);
+ const request = useApiCall("/setup-keys/" + setupKey.id);
const { mutate } = useSWRConfig();
const handleRevoke = async () => {
+ const choice = await confirm({
+ title: `Revoke '${setupKey?.name || "Setup Key"}'?`,
+ description:
+ "Are you sure you want to revoke the setup key? This action cannot be undone.",
+ confirmText: "Revoke",
+ cancelText: "Cancel",
+ type: "danger",
+ });
+ if (!choice) return;
+
notify({
title: setupKey?.name || "Setup Key",
description: "Setup key was successfully revoked",
- promise: deleteRequest
+ promise: request
.put({
name: setupKey?.name || "Setup Key",
type: setupKey.type,
@@ -37,17 +47,26 @@ export default function SetupKeyActionCell({ setupKey }: Props) {
});
};
- const handleConfirm = async () => {
+ const handleDelete = async () => {
const choice = await confirm({
- title: `Revoke '${setupKey?.name || "Setup Key"}'?`,
+ title: `Delete '${setupKey?.name || "Setup Key"}'?`,
description:
- "Are you sure you want to revoke the setup key? This action cannot be undone.",
- confirmText: "Revoke",
+ "Are you sure you want to delete the setup key? This action cannot be undone.",
+ confirmText: "Delete",
cancelText: "Cancel",
type: "danger",
});
if (!choice) return;
- handleRevoke().then();
+
+ notify({
+ title: setupKey?.name || "Setup Key",
+ description: "Setup key was successfully deleted",
+ promise: request.del().then(() => {
+ mutate("/setup-keys");
+ mutate("/groups");
+ }),
+ loadingMessage: "Deleting the setup key...",
+ });
};
return (
@@ -55,12 +74,16 @@ export default function SetupKeyActionCell({ setupKey }: Props) {
+
);
}
diff --git a/src/modules/setup-keys/SetupKeyGroupsCell.tsx b/src/modules/setup-keys/SetupKeyGroupsCell.tsx
index b35abe1..25e9429 100644
--- a/src/modules/setup-keys/SetupKeyGroupsCell.tsx
+++ b/src/modules/setup-keys/SetupKeyGroupsCell.tsx
@@ -9,7 +9,7 @@ import GroupsRow from "@/modules/common-table-rows/GroupsRow";
type Props = {
setupKey: SetupKey;
};
-export default function SetupKeyGroupsCell({ setupKey }: Props) {
+export default function SetupKeyGroupsCell({ setupKey }: Readonly) {
const [modal, setModal] = useState(false);
const request = useApiCall("/setup-keys/" + setupKey.id);
const { mutate } = useSWRConfig();
diff --git a/src/modules/setup-keys/SetupKeyKeyCell.tsx b/src/modules/setup-keys/SetupKeyKeyCell.tsx
index bb9fbd1..2f903b8 100644
--- a/src/modules/setup-keys/SetupKeyKeyCell.tsx
+++ b/src/modules/setup-keys/SetupKeyKeyCell.tsx
@@ -5,7 +5,7 @@ type Props = {
text: string;
};
-export default function SetupKeyKeyCell({ text }: Props) {
+export default function SetupKeyKeyCell({ text }: Readonly) {
return (
diff --git a/src/modules/setup-keys/SetupKeyModal.tsx b/src/modules/setup-keys/SetupKeyModal.tsx
index 1dc3c6e..3192cff 100644
--- a/src/modules/setup-keys/SetupKeyModal.tsx
+++ b/src/modules/setup-keys/SetupKeyModal.tsx
@@ -42,7 +42,11 @@ type Props = {
setOpen: (open: boolean) => void;
};
const copyMessage = "Setup-Key was copied to your clipboard!";
-export default function SetupKeyModal({ children, open, setOpen }: Props) {
+export default function SetupKeyModal({
+ children,
+ open,
+ setOpen,
+}: Readonly) {
const [successModal, setSuccessModal] = useState(false);
const [setupKey, setSetupKey] = useState();
const [, copy] = useCopyToClipboard(setupKey?.key);
@@ -131,7 +135,7 @@ type ModalProps = {
onSuccess?: (setupKey: SetupKey) => void;
};
-export function SetupKeyModalContent({ onSuccess }: ModalProps) {
+export function SetupKeyModalContent({ onSuccess }: Readonly) {
const setupKeyRequest = useApiCall("/setup-keys", true);
const { mutate } = useSWRConfig();
@@ -149,18 +153,10 @@ export function SetupKeyModalContent({ onSuccess }: ModalProps) {
return reusable ? "Unlimited" : "1";
}, [reusable]);
- const expiresInError = useMemo(() => {
- const expires = parseInt(expiresIn);
- if (expires < 1 || expires > 365) {
- return "Days should be between 1 and 365";
- }
- return "";
- }, [expiresIn]);
-
const isDisabled = useMemo(() => {
const trimmedName = trim(name);
- return trimmedName.length === 0 || expiresInError.length > 0;
- }, [name, expiresInError]);
+ return trimmedName.length === 0;
+ }, [name]);
const submit = () => {
if (!selectedGroups) return;
@@ -174,7 +170,7 @@ export function SetupKeyModalContent({ onSuccess }: ModalProps) {
.post({
name,
type: reusable ? "reusable" : "one-off",
- expires_in: parseInt(expiresIn ? expiresIn : "7") * 24 * 60 * 60, // Days to seconds, defaults to 7 days
+ expires_in: parseInt(expiresIn || "0") * 24 * 60 * 60, // Days to seconds, defaults to 7 days
revoked: false,
auto_groups: groups.map((group) => group.id),
usage_limit: reusable ? parseInt(usageLimit) : 1,
@@ -253,15 +249,16 @@ export function SetupKeyModalContent({ onSuccess }: ModalProps) {
- Should be between 1 and 365 days.
+
+ Days until the key expires.
+ Leave empty for no expiration.
+
) {
return (
) {
return (
diff --git a/src/modules/setup-keys/SetupKeysTable.tsx b/src/modules/setup-keys/SetupKeysTable.tsx
index 6ade803..120c31a 100644
--- a/src/modules/setup-keys/SetupKeysTable.tsx
+++ b/src/modules/setup-keys/SetupKeysTable.tsx
@@ -8,6 +8,7 @@ import DataTableRefreshButton from "@components/table/DataTableRefreshButton";
import { DataTableRowsPerPage } from "@components/table/DataTableRowsPerPage";
import GetStartedTest from "@components/ui/GetStartedTest";
import { ColumnDef, SortingState } from "@tanstack/react-table";
+import dayjs from "dayjs";
import { ExternalLinkIcon, PlusCircle } from "lucide-react";
import { usePathname } from "next/navigation";
import React, { useState } from "react";
@@ -15,6 +16,7 @@ import { useSWRConfig } from "swr";
import SetupKeysIcon from "@/assets/icons/SetupKeysIcon";
import { useLocalStorage } from "@/hooks/useLocalStorage";
import { SetupKey } from "@/interfaces/SetupKey";
+import EmptyRow from "@/modules/common-table-rows/EmptyRow";
import ExpirationDateRow from "@/modules/common-table-rows/ExpirationDateRow";
import LastTimeRow from "@/modules/common-table-rows/LastTimeRow";
import SetupKeyActionCell from "@/modules/setup-keys/SetupKeyActionCell";
@@ -94,7 +96,15 @@ export const SetupKeysTableColumns: ColumnDef[] = [
header: ({ column }) => {
return Expires;
},
- cell: ({ row }) => ,
+ cell: ({ row }) => {
+ let expires = dayjs(row.original.expires);
+ let isNeverExpiring = expires?.year() == 1 || false;
+ return !isNeverExpiring ? (
+
+ ) : (
+
+ );
+ },
},
{
@@ -116,7 +126,7 @@ export default function SetupKeysTable({
setupKeys,
isLoading,
headingTarget,
-}: Props) {
+}: Readonly) {
const { mutate } = useSWRConfig();
const path = usePathname();
@@ -216,6 +226,20 @@ export default function SetupKeysTable({
{(table) => (
<>
+ {
+ table.setPageIndex(0);
+ table.getColumn("valid")?.setFilterValue(undefined);
+ }}
+ disabled={setupKeys?.length == 0}
+ variant={
+ table.getColumn("valid")?.getFilterValue() == undefined
+ ? "tertiary"
+ : "secondary"
+ }
+ >
+ All
+
{
table.setPageIndex(0);
@@ -233,16 +257,16 @@ export default function SetupKeysTable({
{
table.setPageIndex(0);
- table.getColumn("valid")?.setFilterValue("");
+ table.getColumn("valid")?.setFilterValue(false);
}}
disabled={setupKeys?.length == 0}
variant={
- table.getColumn("valid")?.getFilterValue() != true
+ table.getColumn("valid")?.getFilterValue() == false
? "tertiary"
: "secondary"
}
>
- All
+ Expired