import { useEffect, useState } from "react" import moment from "moment" import { debounce } from "lodash" import { Column, Row, usePagination, useTable } from "react-table" import { useAdminDeletePublishableApiKey, useAdminPublishableApiKeys, useAdminRevokePublishableApiKey, } from "medusa-react" import { PublishableApiKey } from "@medusajs/medusa" import { Translation, useTranslation } from "react-i18next" import TableContainer from "../../../components/organisms/table-container" import Table from "../../../components/molecules/table" import { ActionType } from "../../../components/molecules/actionables" import TrashIcon from "../../../components/fundamentals/icons/trash-icon" import ClipboardCopyIcon from "../../../components/fundamentals/icons/clipboard-copy-icon" import EditIcon from "../../../components/fundamentals/icons/edit-icon" import StatusIndicator from "../../../components/fundamentals/status-indicator" import StopIcon from "../../../components/fundamentals/icons/stop-icon" import Tooltip from "../../../components/atoms/tooltip" import CheckIcon from "../../../components/fundamentals/icons/check-icon" import DeletePrompt from "../../../components/organisms/delete-prompt" const PAGE_SIZE = 12 const COLUMNS: Column[] = [ { accessor: "title", Header: (
{(t) => t("tables-name", "Name")}
), Cell: ({ row: { original } }) => { return {original.title} }, }, { accessor: "id", Header: (
{" "} {(t) => t("tables-token", "Token")}
), Cell: ({ row: { original } }) => { const [copied, setCopied] = useState(false) const onClick = () => { setCopied(true) navigator.clipboard.writeText(original.id) } return ( setCopied(false), 1000)} content={ copied ? ( {" "} {(t) => t("tables-done", "done")} ) : ( {(t) => t("tables-copy-to-clipboard", "Copy to clipboard")} ) } > {original.id} ) }, }, { accessor: "created_at", Header: (
{" "} {(t) => t("tables-created", "Created")}
), Cell: ({ row: { original } }) => { return ( {moment(original.created_at).format("MMM Do YYYY, h:mm:ss")} ) }, }, { accessor: "revoked_at", Header: (
{" "} {(t) => t("tables-status", "Status")}
), Cell: ({ row: { original } }) => { const { t } = useTranslation() return ( {original.revoked_at ? ( ) : ( )} ) }, }, ] type PublishableKeyTableRowProps = { row: Row isRevoked: boolean showDetails: () => void showChannelsModal: () => void } /** * Component rendering a single PK table row. */ function PublishableKeyTableRow(props: PublishableKeyTableRowProps) { const { row, isRevoked, showChannelsModal, showDetails } = props const pubKeyId = row.original.id const [showDelete, setShowDelete] = useState(false) const [showRevoke, setShowRevoke] = useState(false) const { t } = useTranslation() const { mutateAsync: revokePublicKey } = useAdminRevokePublishableApiKey(pubKeyId) const { mutateAsync: deletePublicKey } = useAdminDeletePublishableApiKey(pubKeyId) const actions: ActionType[] = [ { label: t("tables-edit-api-key-details", "Edit API key details"), onClick: showDetails, icon: , }, { label: t("tables-edit-sales-channels", "Edit sales channels"), onClick: showChannelsModal, icon: , }, { label: t("tables-copy-token", "Copy token"), onClick: () => navigator.clipboard.writeText(pubKeyId), icon: , }, { label: t("tables-revoke-token", "Revoke token"), onClick: () => setShowRevoke(true), icon: , disabled: isRevoked, }, { label: t("tables-delete-api-key", "Delete API key"), onClick: () => setShowDelete(true), icon: , variant: "danger", }, ] return ( <> {props.row.cells.map((cell) => ( {cell.render("Cell")} ))} {showDelete && ( setShowDelete(false)} onDelete={async () => deletePublicKey()} confirmText={t("tables-yes-delete", "Yes, delete")} successText={t("tables-api-key-deleted", "API key deleted")} text={t( "tables-are-you-sure-you-want-to-delete-this-public-key", "Are you sure you want to delete this public key?" )} heading={t("tables-delete-key", "Delete key")} /> )} {showRevoke && ( setShowRevoke(false)} onDelete={async () => revokePublicKey()} confirmText={t("tables-yes-revoke", "Yes, revoke")} successText={t("tables-api-key-revoked", "API key revoked")} text={t( "tables-are-you-sure-you-want-to-revoke-this-public-key", "Are you sure you want to revoke this public key?" )} heading={t("tables-revoke-key", "Revoke key")} /> )} ) } type PublishableApiKeysTableProps = { showDetailsModal: (pubKey: PublishableApiKey) => void showChannelsModal: (pubKey: PublishableApiKey) => void } /** * Container component that displays paginated publishable api keys table. */ function PublishableApiKeysTable(props: PublishableApiKeysTableProps) { const [offset, setOffset] = useState(0) const [numPages, setNumPages] = useState(0) const [currentPage, setCurrentPage] = useState(0) const { t } = useTranslation() const { publishable_api_keys: keys, count, isLoading, } = useAdminPublishableApiKeys({ offset, limit: PAGE_SIZE }) const table = useTable( { columns: COLUMNS, data: keys || [], manualPagination: true, initialState: { pageIndex: currentPage, pageSize: PAGE_SIZE, selectedRowIds: {}, }, pageCount: numPages, autoResetSelectedRows: false, autoResetPage: false, getRowId: (row) => row.id, }, usePagination ) useEffect(() => { if (typeof count !== "undefined") { setNumPages(Math.ceil(count / PAGE_SIZE)) } }, [count]) const handleNext = () => { if (table.canNextPage) { setOffset((old) => old + table.state.pageSize) setCurrentPage((old) => old + 1) table.nextPage() } } const handlePrev = () => { if (table.canPreviousPage) { setOffset((old) => Math.max(old - table.state.pageSize, 0)) setCurrentPage((old) => old - 1) table.previousPage() } } return ( {/* === HEADER === */} {table.headerGroups.map((headerGroup) => ( {headerGroup.headers.map((col) => ( {col.render("Header")} ))} ))} {/* === BODY === */} {table.rows.map((row) => { table.prepareRow(row) return ( props.showDetailsModal(row.original)} showChannelsModal={() => props.showChannelsModal(row.original)} isRevoked={!!row.original.revoked_at} /> ) })}
{/* === PLACEHOLDER === */} {!keys?.length && !isLoading && (
{t( "tables-no-keys-yet-use-the-above-button-to-create-your-first-publishable-key", "No keys yet, use the above button to create your first publishable key" )}
)}
) } export default PublishableApiKeysTable