💄 show approval state in the user device uI

This commit is contained in:
Fred KISSIE
2026-01-14 01:59:51 +01:00
parent 30943010e6
commit 4c78e93143
5 changed files with 43 additions and 34 deletions

View File

@@ -455,7 +455,10 @@
"selectApprovalState": "Select Approval State", "selectApprovalState": "Select Approval State",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filter By Approval State",
"approvalListEmpty": "No approval yet at the moment", "approvalListEmpty": "No approval yet at the moment",
"approvalState": "Approval State",
"approve": "Approve", "approve": "Approve",
"approved": "Approved",
"denied": "Denied",
"deny": "Deny", "deny": "Deny",
"viewDetails": "View Details", "viewDetails": "View Details",
"requestingNewDeviceApproval": "is requesting new device", "requestingNewDeviceApproval": "is requesting new device",

View File

@@ -136,7 +136,8 @@ function queryClients(
username: users.username, username: users.username,
userEmail: users.email, userEmail: users.email,
niceId: clients.niceId, niceId: clients.niceId,
agent: olms.agent agent: olms.agent,
approvalState: clients.approvalState
}) })
.from(clients) .from(clients)
.leftJoin(orgs, eq(clients.orgId, orgs.orgId)) .leftJoin(orgs, eq(clients.orgId, orgs.orgId))

View File

@@ -4,7 +4,7 @@ import { AxiosResponse } from "axios";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle"; import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { ListClientsResponse } from "@server/routers/client"; import { ListClientsResponse } from "@server/routers/client";
import { getTranslations } from "next-intl/server"; import { getTranslations } from "next-intl/server";
import type { ClientRow } from "@app/components/MachineClientsTable"; import type { ClientRow } from "@app/components/UserDevicesTable";
import UserDevicesTable from "@app/components/UserDevicesTable"; import UserDevicesTable from "@app/components/UserDevicesTable";
type ClientsPageProps = { type ClientsPageProps = {
@@ -55,7 +55,8 @@ export default async function ClientsPage(props: ClientsPageProps) {
username: client.username, username: client.username,
userEmail: client.userEmail, userEmail: client.userEmail,
niceId: client.niceId, niceId: client.niceId,
agent: client.agent agent: client.agent,
approvalState: client.approvalState ?? "approved"
}; };
}; };

View File

@@ -35,6 +35,7 @@ export type ClientRow = {
userEmail: string | null; userEmail: string | null;
niceId: string; niceId: string;
agent: string | null; agent: string | null;
approvalState: "approved" | "pending" | "denied";
}; };
type ClientTableProps = { type ClientTableProps = {

View File

@@ -1,9 +1,8 @@
"use client"; "use client";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog"; import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import { DataTable } from "@app/components/ui/data-table";
import { ExtendedColumnDef } from "@app/components/ui/data-table";
import { Button } from "@app/components/ui/button"; import { Button } from "@app/components/ui/button";
import { DataTable, ExtendedColumnDef } from "@app/components/ui/data-table";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@@ -23,9 +22,11 @@ import { useTranslations } from "next-intl";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useMemo, useState, useTransition } from "react"; import { useMemo, useState, useTransition } from "react";
import { Badge } from "./ui/badge";
import { InfoPopup } from "./ui/info-popup";
import ClientDownloadBanner from "./ClientDownloadBanner"; import ClientDownloadBanner from "./ClientDownloadBanner";
import { Badge } from "./ui/badge";
import { build } from "@server/build";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { t } from "@faker-js/faker/dist/airline-DF6RqYmq";
export type ClientRow = { export type ClientRow = {
id: number; id: number;
@@ -43,6 +44,7 @@ export type ClientRow = {
userEmail: string | null; userEmail: string | null;
niceId: string; niceId: string;
agent: string | null; agent: string | null;
approvalState: "approved" | "pending" | "denied";
}; };
type ClientTableProps = { type ClientTableProps = {
@@ -59,6 +61,8 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
null null
); );
const { isPaidUser } = usePaidStatus();
const api = createApiClient(useEnvContext()); const api = createApiClient(useEnvContext());
const [isRefreshing, startTransition] = useTransition(); const [isRefreshing, startTransition] = useTransition();
@@ -179,33 +183,6 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
); );
} }
}, },
// {
// accessorKey: "siteName",
// header: ({ column }) => {
// return (
// <Button
// variant="ghost"
// onClick={() =>
// column.toggleSorting(column.getIsSorted() === "asc")
// }
// >
// Site
// <ArrowUpDown className="ml-2 h-4 w-4" />
// </Button>
// );
// },
// cell: ({ row }) => {
// const r = row.original;
// return (
// <Link href={`/${r.orgId}/settings/sites/${r.siteId}`}>
// <Button variant="outline">
// {r.siteName}
// <ArrowUpRight className="ml-2 h-4 w-4" />
// </Button>
// </Link>
// );
// }
// },
{ {
accessorKey: "online", accessorKey: "online",
friendlyName: "Connectivity", friendlyName: "Connectivity",
@@ -342,6 +319,32 @@ export default function UserDevicesTable({ userClients }: ClientTableProps) {
} }
]; ];
if (build !== "oss" && isPaidUser) {
// insert as the 3rd item
baseColumns.splice(3, 0, {
id: "approvalState",
enableHiding: false,
header: () => <span className="p-3">{t("approvalState")}</span>,
cell: ({ row }) => {
const { approvalState } = row.original;
switch (approvalState) {
case "approved":
return (
<Badge variant="green">{t("approved")}</Badge>
);
case "denied":
return <Badge variant="red">{t("denied")}</Badge>;
default:
return (
<Badge variant="secondary">
{t("pending")}
</Badge>
);
}
}
});
}
baseColumns.push({ baseColumns.push({
id: "actions", id: "actions",
enableHiding: false, enableHiding: false,