diff --git a/.changeset/purple-bats-clap.md b/.changeset/purple-bats-clap.md new file mode 100644 index 0000000000..2c8c16fb87 --- /dev/null +++ b/.changeset/purple-bats-clap.md @@ -0,0 +1,7 @@ +--- +"@medusajs/medusa": patch +"medusa-react": patch +"@medusajs/admin": patch +--- + +feat: Admin V2 API keys diff --git a/packages/admin-next/dashboard/public/locales/en-US/translation.json b/packages/admin-next/dashboard/public/locales/en-US/translation.json index b7f5304dfa..0c9a9ae959 100644 --- a/packages/admin-next/dashboard/public/locales/en-US/translation.json +++ b/packages/admin-next/dashboard/public/locales/en-US/translation.json @@ -803,9 +803,10 @@ "deleteSalesChannelWarning": "You are about to delete the sales channel {{name}}. This action cannot be undone." }, "apiKeyManagement": { - "domain": "API Key Management", + "domainTitle": "API Keys", + "domain": "{{ keyType }} API Keys", "createKey": "Create key", - "createPublishableApiKey": "Create Publishable API Key", + "createPublishableApiKey": "Create {{ keyType }} API Key", "editKey": "Edit key", "revoke": "Revoke", "publishableApiKeyHint": "Publishable API keys are used to limit the scope of requests to specific sales channels.", diff --git a/packages/admin-next/dashboard/src/components/layout/settings-layout/settings-layout.tsx b/packages/admin-next/dashboard/src/components/layout/settings-layout/settings-layout.tsx index 8204ae3eaf..95da98bba2 100644 --- a/packages/admin-next/dashboard/src/components/layout/settings-layout/settings-layout.tsx +++ b/packages/admin-next/dashboard/src/components/layout/settings-layout/settings-layout.tsx @@ -64,7 +64,7 @@ const useDeveloperRoutes = (): NavItemProps[] => { return useMemo( () => [ { - label: t("apiKeyManagement.domain"), + label: t("apiKeyManagement.domainTitle"), to: "/settings/api-key-management", }, { diff --git a/packages/admin-next/dashboard/src/components/search/search.tsx b/packages/admin-next/dashboard/src/components/search/search.tsx index d7fcfad992..cb78cf7727 100644 --- a/packages/admin-next/dashboard/src/components/search/search.tsx +++ b/packages/admin-next/dashboard/src/components/search/search.tsx @@ -111,7 +111,7 @@ const useLinks = (): CommandGroupProps[] => { label: t("salesChannels.domain"), }, { - label: t("apiKeyManagement.domain"), + label: t("apiKeyManagement.domainTitle"), }, ], }, diff --git a/packages/admin-next/dashboard/src/lib/uppercase-first.ts b/packages/admin-next/dashboard/src/lib/uppercase-first.ts new file mode 100644 index 0000000000..0112f4e293 --- /dev/null +++ b/packages/admin-next/dashboard/src/lib/uppercase-first.ts @@ -0,0 +1,4 @@ +export function upperCaseFirst(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1) + } + \ No newline at end of file diff --git a/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx b/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx index d7f61a8d09..9436c1b32c 100644 --- a/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx +++ b/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx @@ -768,58 +768,6 @@ export const v1Routes: RouteObject[] = [ }, ], }, - { - path: "api-key-management", - element: , - handle: { - crumb: () => "API Key Management", - }, - children: [ - { - path: "", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-list" - ), - children: [ - { - path: "create", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-create" - ), - }, - ], - }, - { - path: ":id", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-detail" - ), - handle: { - crumb: (data: AdminPublishableApiKeysRes) => - data.publishable_api_key.title, - }, - children: [ - { - path: "edit", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-edit" - ), - }, - { - path: "add-sales-channels", - lazy: () => - import( - "../../routes/api-key-management/api-key-management-add-sales-channels" - ), - }, - ], - }, - ], - }, ...settingsExtensions, ], }, diff --git a/packages/admin-next/dashboard/src/providers/router-provider/v2.tsx b/packages/admin-next/dashboard/src/providers/router-provider/v2.tsx index b70a0a6c8e..4f5080ef21 100644 --- a/packages/admin-next/dashboard/src/providers/router-provider/v2.tsx +++ b/packages/admin-next/dashboard/src/providers/router-provider/v2.tsx @@ -8,6 +8,7 @@ import { Outlet } from "react-router-dom" import { SearchProvider } from "../search-provider" import { SettingsLayout } from "../../components/layout/settings-layout" import { SidebarProvider } from "../sidebar-provider" +import { ApiKeyDTO } from "@medusajs/types" import { Spinner } from "@medusajs/icons" import { useV2Session } from "../../lib/api-v2" @@ -332,6 +333,57 @@ export const v2Routes: RouteObject[] = [ }, ], }, + { + path: "api-key-management", + element: , + handle: { + crumb: () => "API Key Management", + }, + children: [ + { + path: "", + lazy: () => + import( + "../../v2-routes/api-key-management/api-key-management-list" + ), + children: [ + { + path: "create", + lazy: () => + import( + "../../v2-routes/api-key-management/api-key-management-create" + ), + }, + ], + }, + { + path: ":id", + lazy: () => + import( + "../../v2-routes/api-key-management/api-key-management-detail" + ), + handle: { + crumb: (data: { api_key: ApiKeyDTO }) => data.api_key.title, + }, + children: [ + { + path: "edit", + lazy: () => + import( + "../../v2-routes/api-key-management/api-key-management-edit" + ), + }, + { + path: "add-sales-channels", + lazy: () => + import( + "../../v2-routes/api-key-management/api-key-management-add-sales-channels" + ), + }, + ], + }, + ], + }, ], }, ], diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/api-key-management-add-sales-channels.tsx b/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/api-key-management-add-sales-channels.tsx deleted file mode 100644 index 8c1e34155a..0000000000 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/api-key-management-add-sales-channels.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { useAdminPublishableApiKeySalesChannels } from "medusa-react" -import { useParams } from "react-router-dom" -import { RouteFocusModal } from "../../../components/route-modal" -import { AddSalesChannelsToApiKeyForm } from "./components" - -export const ApiKeyManagementAddSalesChannels = () => { - const { id } = useParams() - - const { sales_channels, isLoading, isError, error } = - useAdminPublishableApiKeySalesChannels(id!) - - if (isError) { - throw error - } - - return ( - - {!isLoading && sales_channels && ( - sc.id)} - /> - )} - - ) -} diff --git a/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/api-key-management-add-sales-channels.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/api-key-management-add-sales-channels.tsx new file mode 100644 index 0000000000..02c713df61 --- /dev/null +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/api-key-management-add-sales-channels.tsx @@ -0,0 +1,36 @@ +import { adminPublishableApiKeysKeys, useAdminCustomQuery } from "medusa-react" +import { useParams } from "react-router-dom" +import { RouteFocusModal } from "../../../components/route-modal" +import { AddSalesChannelsToApiKeyForm } from "./components" + +export const ApiKeyManagementAddSalesChannels = () => { + const { id } = useParams() + + const { data, isLoading, isError, error } = useAdminCustomQuery( + `/api-keys/${id}`, + [adminPublishableApiKeysKeys.detailSalesChannels(id!)], + { + fields: "id,*sales_channels", + }, + { + keepPreviousData: true, + } + ) + + if (isError) { + throw error + } + + const salesChannels = data?.api_key?.sales_channels + + return ( + + {!isLoading && salesChannels && ( + sc.id)} + /> + )} + + ) +} diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/components/add-sales-channels-to-api-key-form.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/components/add-sales-channels-to-api-key-form.tsx similarity index 96% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/components/add-sales-channels-to-api-key-form.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/components/add-sales-channels-to-api-key-form.tsx index d81c3faca1..b94fde8aa1 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/components/add-sales-channels-to-api-key-form.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/components/add-sales-channels-to-api-key-form.tsx @@ -18,7 +18,9 @@ import { useReactTable, } from "@tanstack/react-table" import { + adminPublishableApiKeysKeys, useAdminAddPublishableKeySalesChannelsBatch, + useAdminCustomPost, useAdminSalesChannels, } from "medusa-react" import { useEffect, useMemo, useState } from "react" @@ -61,8 +63,10 @@ export const AddSalesChannelsToApiKeyForm = ({ const { setValue } = form - const { mutateAsync, isLoading: isMutating } = - useAdminAddPublishableKeySalesChannelsBatch(apiKey) + const { mutateAsync, isLoading: isMutating } = useAdminCustomPost( + `/api-keys/${apiKey}/sales-channels/batch/add`, + [adminPublishableApiKeysKeys.detailSalesChannels(apiKey)] + ) const [{ pageIndex, pageSize }, setPagination] = useState({ pageIndex: 0, @@ -128,7 +132,7 @@ export const AddSalesChannelsToApiKeyForm = ({ const handleSubmit = form.handleSubmit(async (values) => { await mutateAsync( { - sales_channel_ids: values.sales_channel_ids.map((p) => ({ id: p })), + sales_channel_ids: values.sales_channel_ids, }, { onSuccess: () => { diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/components/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/components/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/components/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/components/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-add-sales-channels/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-add-sales-channels/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/api-key-management-create.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/api-key-management-create.tsx similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/api-key-management-create.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/api-key-management-create.tsx diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/create-publishable-api-key-form.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/create-publishable-api-key-form.tsx similarity index 87% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/create-publishable-api-key-form.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/create-publishable-api-key-form.tsx index 10300524cc..cadc874f86 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/create-publishable-api-key-form.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/create-publishable-api-key-form.tsx @@ -1,6 +1,6 @@ import { zodResolver } from "@hookform/resolvers/zod" import { Button, Heading, Input, Text } from "@medusajs/ui" -import { useAdminCreatePublishableApiKey } from "medusa-react" +import { adminPublishableApiKeysKeys, useAdminCustomPost } from "medusa-react" import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" import * as zod from "zod" @@ -26,14 +26,19 @@ export const CreatePublishableApiKeyForm = () => { resolver: zodResolver(CreatePublishableApiKeySchema), }) - const { mutateAsync, isLoading } = useAdminCreatePublishableApiKey() + const { mutateAsync, isLoading } = useAdminCustomPost(`/admin/api-keys`, [ + adminPublishableApiKeysKeys.lists(), + ]) const handleSubmit = form.handleSubmit(async (values) => { - await mutateAsync(values, { - onSuccess: ({ publishable_api_key }) => { - handleSuccess(`/settings/api-key-management/${publishable_api_key.id}`) - }, - }) + await mutateAsync( + { title: values.title, type: "publishable" }, + { + onSuccess: () => { + handleSuccess(`/settings/api-key-management`) + }, + } + ) }) return ( diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/components/create-publishable-api-key-form/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-create/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-create/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/api-key-management-detail.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/api-key-management-detail.tsx similarity index 61% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/api-key-management-detail.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/api-key-management-detail.tsx index 358886d640..d31d4d7b8b 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/api-key-management-detail.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/api-key-management-detail.tsx @@ -1,4 +1,4 @@ -import { useAdminPublishableApiKey } from "medusa-react" +import { adminPublishableApiKeysKeys, useAdminCustomQuery } from "medusa-react" import { Outlet, json, useLoaderData, useParams } from "react-router-dom" import { JsonViewSection } from "../../../components/common/json-view-section" import { ApiKeyGeneralSection } from "./components/api-key-general-section" @@ -11,16 +11,20 @@ export const ApiKeyManagementDetail = () => { > const { id } = useParams() - const { publishable_api_key, isLoading, isError, error } = - useAdminPublishableApiKey(id!, { - initialData, - }) + const { data, isLoading, isError, error } = useAdminCustomQuery( + `/api-keys/${id}`, + [adminPublishableApiKeysKeys.detail(id!)], + undefined, + { + initialData: initialData, + } + ) if (isLoading) { return
Loading...
} - if (isError || !publishable_api_key) { + if (isError || !data?.api_key) { if (error) { throw error } @@ -30,9 +34,9 @@ export const ApiKeyManagementDetail = () => { return (
- - - + + +
) diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-general-section/api-key-general-section.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-general-section/api-key-general-section.tsx similarity index 93% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-general-section/api-key-general-section.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-general-section/api-key-general-section.tsx index a33f7f286d..3074fba327 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-general-section/api-key-general-section.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-general-section/api-key-general-section.tsx @@ -9,6 +9,7 @@ import { usePrompt, } from "@medusajs/ui" import { + useAdminCustomQuery, useAdminDeletePublishableApiKey, useAdminRevokePublishableApiKey, useAdminUser, @@ -18,9 +19,10 @@ import { useNavigate } from "react-router-dom" import { ActionMenu } from "../../../../../components/common/action-menu" import { Skeleton } from "../../../../../components/common/skeleton" import { UserLink } from "../../../../../components/common/user-link" +import { ApiKeyDTO } from "@medusajs/types" type ApiKeyGeneralSectionProps = { - apiKey: PublishableApiKey + apiKey: ApiKeyDTO } export const ApiKeyGeneralSection = ({ apiKey }: ApiKeyGeneralSectionProps) => { @@ -121,10 +123,10 @@ export const ApiKeyGeneralSection = ({ apiKey }: ApiKeyGeneralSectionProps) => {
- {apiKey.id} + {apiKey.redacted} @@ -149,9 +151,12 @@ export const ApiKeyGeneralSection = ({ apiKey }: ApiKeyGeneralSectionProps) => { } const ActionBy = ({ userId }: { userId: string | null }) => { - const { user, isLoading, isError, error } = useAdminUser(userId!, { - enabled: !!userId, - }) + const { data, isLoading, isError, error } = useAdminCustomQuery( + `/users/${userId}`, + [], + {}, + { enabled: !!userId } + ) if (!userId) { return ( @@ -174,7 +179,7 @@ const ActionBy = ({ userId }: { userId: string | null }) => { ) } - if (!user) { + if (!data?.user) { return ( - @@ -182,5 +187,5 @@ const ActionBy = ({ userId }: { userId: string | null }) => { ) } - return + return } diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-general-section/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-general-section/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-general-section/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-general-section/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/api-key-sales-channel-section.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/api-key-sales-channel-section.tsx similarity index 91% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/api-key-sales-channel-section.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/api-key-sales-channel-section.tsx index 8faf515508..26a84282d1 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/api-key-sales-channel-section.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/api-key-sales-channel-section.tsx @@ -20,7 +20,9 @@ import { useReactTable, } from "@tanstack/react-table" import { - useAdminPublishableApiKeySalesChannels, + adminPublishableApiKeysKeys, + useAdminCustomPost, + useAdminCustomQuery, useAdminRemovePublishableKeySalesChannelsBatch, } from "medusa-react" import { useMemo, useState } from "react" @@ -34,9 +36,10 @@ import { import { Query } from "../../../../../components/filtering/query" import { LocalizedTablePagination } from "../../../../../components/localization/localized-table-pagination" import { useQueryParams } from "../../../../../hooks/use-query-params" +import { ApiKeyDTO } from "@medusajs/types" type ApiKeySalesChannelSectionProps = { - apiKey: PublishableApiKey + apiKey: ApiKeyDTO } const PAGE_SIZE = 10 @@ -64,23 +67,28 @@ export const ApiKeySalesChannelSection = ({ const [rowSelection, setRowSelection] = useState({}) const params = useQueryParams(["q"]) - const { sales_channels, isLoading, isError, error } = - useAdminPublishableApiKeySalesChannels( - apiKey.id, - { - ...params, - }, - { - keepPreviousData: true, - } - ) - const count = sales_channels?.length || 0 + const query = { + ...params, + fields: "id,*sales_channels", + } + + const { data, isLoading, isError, error } = useAdminCustomQuery( + `/api-keys/${apiKey.id}`, + [adminPublishableApiKeysKeys.detailSalesChannels(apiKey.id, query)], + query, + { + keepPreviousData: true, + } + ) + + const salesChannels = data?.api_key?.sales_channels + const count = salesChannels?.length || 0 const columns = useColumns() const table = useReactTable({ - data: sales_channels ?? [], + data: salesChannels ?? [], columns, pageCount: Math.ceil(count / PAGE_SIZE), state: { @@ -97,8 +105,9 @@ export const ApiKeySalesChannelSection = ({ }, }) - const { mutateAsync } = useAdminRemovePublishableKeySalesChannelsBatch( - apiKey.id + const { mutateAsync } = useAdminCustomPost( + `/api-keys/${apiKey.id}/sales-channels/batch/remove`, + [adminPublishableApiKeysKeys.detailSalesChannels(apiKey.id)] ) const handleRemove = async () => { @@ -119,7 +128,7 @@ export const ApiKeySalesChannelSection = ({ await mutateAsync( { - sales_channel_ids: keys.map((k) => ({ id: k })), + sales_channel_ids: keys, }, { onSuccess: () => { @@ -129,7 +138,7 @@ export const ApiKeySalesChannelSection = ({ ) } - const noRecords = !isLoading && !sales_channels?.length && !params.q + const noRecords = !isLoading && !salesChannels?.length && !params.q if (isError) { throw error @@ -155,7 +164,7 @@ export const ApiKeySalesChannelSection = ({ ) : (
- {!isLoading && sales_channels?.length !== 0 ? ( + {!isLoading && salesChannels?.length !== 0 ? ( {table.getHeaderGroups().map((headerGroup) => { diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/components/api-key-sales-channel-section/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/loader.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/loader.ts similarity index 59% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/loader.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/loader.ts index 66034bcebb..c24627accb 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-detail/loader.ts +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-detail/loader.ts @@ -1,13 +1,13 @@ -import { AdminPublishableApiKeysRes } from "@medusajs/medusa" import { Response } from "@medusajs/medusa-js" -import { adminProductKeys } from "medusa-react" +import { adminPublishableApiKeysKeys } from "medusa-react" import { LoaderFunctionArgs } from "react-router-dom" +import { ApiKeyDTO } from "@medusajs/types" import { medusa, queryClient } from "../../../lib/medusa" const apiKeyDetailQuery = (id: string) => ({ - queryKey: adminProductKeys.detail(id), - queryFn: async () => medusa.admin.publishableApiKeys.retrieve(id), + queryKey: adminPublishableApiKeysKeys.detail(id), + queryFn: async () => medusa.admin.custom.get(`/api-keys/${id}`), }) export const apiKeyLoader = async ({ params }: LoaderFunctionArgs) => { @@ -15,7 +15,7 @@ export const apiKeyLoader = async ({ params }: LoaderFunctionArgs) => { const query = apiKeyDetailQuery(id!) return ( - queryClient.getQueryData>( + queryClient.getQueryData>( query.queryKey ) ?? (await queryClient.fetchQuery(query)) ) diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx similarity index 50% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx index a8f9c27997..ed7abab7aa 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx @@ -1,7 +1,7 @@ import { Heading } from "@medusajs/ui" -import { useAdminPublishableApiKey } from "medusa-react" +import { adminPublishableApiKeysKeys, useAdminCustomQuery } from "medusa-react" import { useTranslation } from "react-i18next" -import { useParams } from "react-router-dom" +import { json, useParams } from "react-router-dom" import { RouteDrawer } from "../../../components/route-modal" import { EditApiKeyForm } from "./components/edit-api-key-form" @@ -9,11 +9,17 @@ export const ApiKeyManagementEdit = () => { const { id } = useParams() const { t } = useTranslation() - const { publishable_api_key, isLoading, isError, error } = - useAdminPublishableApiKey(id!) + const { data, isLoading, isError, error } = useAdminCustomQuery( + `/api-keys/${id}`, + [adminPublishableApiKeysKeys.detail(id!)] + ) - if (isError) { - throw error + if (isError || !data?.api_key) { + if (error) { + throw error + } + + throw json("An unknown error has occured", 500) } return ( @@ -21,8 +27,8 @@ export const ApiKeyManagementEdit = () => { {t("apiKeyManagement.editKey")} - {!isLoading && publishable_api_key && ( - + {!isLoading && !!data?.api_key && ( + )} ) diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx similarity index 85% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx index 87798aaff5..3cab495052 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx @@ -1,7 +1,6 @@ import { zodResolver } from "@hookform/resolvers/zod" -import type { PublishableApiKey } from "@medusajs/medusa" import { Button, Input } from "@medusajs/ui" -import { useAdminUpdatePublishableApiKey } from "medusa-react" +import { adminPublishableApiKeysKeys, useAdminCustomPost } from "medusa-react" import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" import * as zod from "zod" @@ -11,9 +10,10 @@ import { RouteDrawer, useRouteModal, } from "../../../../../components/route-modal" +import { ApiKeyDTO } from "@medusajs/types" type EditApiKeyFormProps = { - apiKey: PublishableApiKey + apiKey: ApiKeyDTO } const EditApiKeySchema = zod.object({ @@ -31,7 +31,14 @@ export const EditApiKeyForm = ({ apiKey }: EditApiKeyFormProps) => { resolver: zodResolver(EditApiKeySchema), }) - const { mutateAsync, isLoading } = useAdminUpdatePublishableApiKey(apiKey.id) + const { mutateAsync, isLoading } = useAdminCustomPost( + `/api-keys/${apiKey.id}`, + [ + adminPublishableApiKeysKeys.lists(), + adminPublishableApiKeysKeys.detail(apiKey.id), + adminPublishableApiKeysKeys.details(), + ] + ) const handleSubmit = form.handleSubmit(async (data) => { await mutateAsync(data, { diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/components/edit-api-key-form/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/components/edit-api-key-form/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-edit/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-edit/index.ts diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/api-key-management-list.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/api-key-management-list.tsx similarity index 63% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/api-key-management-list.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/api-key-management-list.tsx index b28f6cae65..bfa5fab652 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/api-key-management-list.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/api-key-management-list.tsx @@ -1,10 +1,13 @@ import { Outlet } from "react-router-dom" import { ApiKeyManagementListTable } from "./components/api-key-management-list-table" +// TODO: Add secret API keys + export const ApiKeyManagementList = () => { return (
- + + {/* */}
) diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/components/api-key-management-list-table/api-key-management-list-table.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/components/api-key-management-list-table/api-key-management-list-table.tsx similarity index 69% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/components/api-key-management-list-table/api-key-management-list-table.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/components/api-key-management-list-table/api-key-management-list-table.tsx index 61b7ea024f..9ab46f920b 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/components/api-key-management-list-table/api-key-management-list-table.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/components/api-key-management-list-table/api-key-management-list-table.tsx @@ -1,5 +1,5 @@ import { Button, Container, Heading } from "@medusajs/ui" -import { useAdminPublishableApiKeys } from "medusa-react" +import { adminPublishableApiKeysKeys, useAdminCustomQuery } from "medusa-react" import { useTranslation } from "react-i18next" import { Link } from "react-router-dom" import { DataTable } from "../../../../../components/table/data-table" @@ -7,30 +7,40 @@ import { useDataTable } from "../../../../../hooks/use-data-table" import { useApiKeyManagementTableColumns } from "./use-api-key-management-table-columns" import { useApiKeyManagementTableFilters } from "./use-api-key-management-table-filters" import { useApiKeyManagementTableQuery } from "./use-api-key-management-table-query" +import { upperCaseFirst } from "../../../../../lib/uppercase-first" const PAGE_SIZE = 20 -export const ApiKeyManagementListTable = () => { +export const ApiKeyManagementListTable = ({ + keyType, +}: { + keyType: "secret" | "publishable" +}) => { const { t } = useTranslation() const { searchParams, raw } = useApiKeyManagementTableQuery({ pageSize: PAGE_SIZE, }) - const { publishable_api_keys, count, isLoading, isError, error } = - useAdminPublishableApiKeys( - { - ...searchParams, - }, - { - keepPreviousData: true, - } - ) + + const query = { + ...searchParams, + type: keyType, + fields: + "id,title,redacted,token,type,created_at,updated_at,revoked_at,last_used_at,created_by,revoked_by", + } + + // @ts-ignore + const { data, count, isLoading, isError, error } = useAdminCustomQuery( + "/api-keys", + [adminPublishableApiKeysKeys.list(query)], + query + ) const filters = useApiKeyManagementTableFilters() const columns = useApiKeyManagementTableColumns() const { table } = useDataTable({ - data: publishable_api_keys || [], + data: data?.api_keys || [], columns, count, enablePagination: true, @@ -49,7 +59,9 @@ export const ApiKeyManagementListTable = () => { return (
- {t("apiKeyManagement.domain")} + + {t(`apiKeyManagement.domain`, { keyType: upperCaseFirst(keyType) })} +
), }), - columnHelper.accessor("id", { - header: "Key", - cell: ({ getValue }) => { + columnHelper.accessor("redacted", { + header: "Token", + cell: ({ getValue, row }) => { const token = getValue() return ( @@ -42,7 +46,7 @@ export const useApiKeyManagementTableColumns = () => { {token} @@ -73,7 +77,7 @@ export const useApiKeyManagementTableColumns = () => { columnHelper.display({ id: "actions", cell: ({ row }) => { - return + return }, }), ], @@ -82,11 +86,19 @@ export const useApiKeyManagementTableColumns = () => { } const ApiKeyActions = ({ apiKey }: { apiKey: PublishableApiKey }) => { - const { mutateAsync: revokeAsync } = useAdminRevokePublishableApiKey( - apiKey.id + const { mutateAsync: revokeAsync } = useAdminCustomPost( + `/api-keys/${apiKey.id}/revoke`, + [ + adminPublishableApiKeysKeys.lists(), + adminPublishableApiKeysKeys.detail(apiKey.id), + ] ) - const { mutateAsync: deleteAsync } = useAdminDeletePublishableApiKey( - apiKey.id + const { mutateAsync: deleteAsync } = useAdminCustomDelete( + `/api-keys/${apiKey.id}`, + [ + adminPublishableApiKeysKeys.lists(), + adminPublishableApiKeysKeys.detail(apiKey.id), + ] ) const { t } = useTranslation() @@ -123,7 +135,7 @@ const ApiKeyActions = ({ apiKey }: { apiKey: PublishableApiKey }) => { return } - await revokeAsync() + await revokeAsync({}) } return ( diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-filters.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-filters.tsx similarity index 57% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-filters.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-filters.tsx index 052e176c6f..d610992456 100644 --- a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-filters.tsx +++ b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-filters.tsx @@ -7,14 +7,10 @@ export const useApiKeyManagementTableFilters = () => { let filters: Filter[] = [] const dateFilters: Filter[] = [ - { label: t("fields.createdAt"), key: "created_at" }, - { label: t("fields.updatedAt"), key: "updated_at" }, - { label: t("fields.revokedAt"), key: "revoked_at" }, - ].map((f) => ({ - key: f.key, - label: f.label, - type: "date", - })) + { label: t("fields.createdAt"), key: "created_at", type: "date" }, + { label: t("fields.updatedAt"), key: "updated_at", type: "date" }, + { label: t("fields.revokedAt"), key: "revoked_at", type: "date" }, + ] filters = [...filters, ...dateFilters] diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-query.tsx b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-query.tsx similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-query.tsx rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/components/api-key-management-list-table/use-api-key-management-table-query.tsx diff --git a/packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/index.ts b/packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/index.ts similarity index 100% rename from packages/admin-next/dashboard/src/routes/api-key-management/api-key-management-list/index.ts rename to packages/admin-next/dashboard/src/v2-routes/api-key-management/api-key-management-list/index.ts diff --git a/packages/medusa-react/src/hooks/index.ts b/packages/medusa-react/src/hooks/index.ts index 2fc1cf4bb5..d7688a759d 100644 --- a/packages/medusa-react/src/hooks/index.ts +++ b/packages/medusa-react/src/hooks/index.ts @@ -1,3 +1,4 @@ export * from "./admin" export * from "./store" export * from "./utils" + diff --git a/packages/medusa/src/api-v2/admin/api-keys/[id]/route.ts b/packages/medusa/src/api-v2/admin/api-keys/[id]/route.ts index 1982d7dba7..843bd43574 100644 --- a/packages/medusa/src/api-v2/admin/api-keys/[id]/route.ts +++ b/packages/medusa/src/api-v2/admin/api-keys/[id]/route.ts @@ -30,7 +30,7 @@ export const GET = async ( const [apiKey] = await remoteQuery(queryObject) - res.status(200).json({ apiKey }) + res.status(200).json({ api_key: apiKey }) } export const POST = async (