@burdenoff/microfe-store 2026.624.2 → 2026.624.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/StoreRoutes.js +3 -3
- package/dist/StoreRoutes.js.map +1 -1
- package/dist/components/AccessDenied.js +3 -3
- package/dist/components/AccessDenied.js.map +1 -1
- package/dist/components/InstallAppModal.js +119 -106
- package/dist/components/InstallAppModal.js.map +1 -1
- package/dist/components/cart/CartDrawer.js +6 -6
- package/dist/components/cart/CartDrawer.js.map +1 -1
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/errors/CombinedGraphQLErrors.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/errors/utils.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/utils.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/core/ApolloLink.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/subscriptions/index.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/utils/createOperation.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/graphql/print.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/caches.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/checkDocument.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/getMainDefinition.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/getOperationDefinition.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/globals/global.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +8 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/makeUniqueId.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/memoize.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/stringifyForDisplay.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/invariant/index.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js +6 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js.map +1 -0
- package/dist/node_modules/{@wry → .bun/@wry_caches@1.0.1/node_modules/@wry}/caches/lib/weak.js +1 -1
- package/dist/node_modules/.bun/@wry_caches@1.0.1/node_modules/@wry/caches/lib/weak.js.map +1 -0
- package/dist/node_modules/{@wry → .bun/@wry_trie@0.5.0/node_modules/@wry}/trie/lib/index.js +1 -1
- package/dist/node_modules/.bun/@wry_trie@0.5.0/node_modules/@wry/trie/lib/index.js.map +1 -0
- package/dist/node_modules/{graphql-ws → .bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws}/dist/client.js +1 -1
- package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/client.js.map +1 -0
- package/dist/node_modules/{graphql-ws → .bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws}/dist/common-CGW11Fyb.js +1 -1
- package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/NotificationFactories.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Observable.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Subscriber.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Subscription.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/config.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/observable/empty.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/scheduler/timeoutProvider.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/symbol/observable.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/UnsubscriptionError.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/createErrorClass.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/errorContext.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/pipe.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/reportUnhandledError.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/tslib@2.8.1}/node_modules/tslib/tslib.es6.js +1 -1
- package/dist/node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.es6.js.map +1 -0
- package/dist/pages/AdminStoresPage.js +372 -390
- package/dist/pages/AdminStoresPage.js.map +1 -1
- package/dist/pages/AdminSubmissionsQueuePage.js +143 -129
- package/dist/pages/AdminSubmissionsQueuePage.js.map +1 -1
- package/dist/pages/InstalledAppsPage.js +133 -110
- package/dist/pages/InstalledAppsPage.js.map +1 -1
- package/dist/pages/MarketplaceHomePage.js +1 -1
- package/dist/pages/MarketplaceHomePage.js.map +1 -1
- package/dist/providers/StoreProvider.js +3 -3
- package/package.json +2 -2
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +0 -1
- package/dist/node_modules/@apollo/client/errors/utils.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/subscriptions/index.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +0 -9
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +0 -8
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +0 -10
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +0 -8
- package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +0 -1
- package/dist/node_modules/@apollo/client/version.js +0 -6
- package/dist/node_modules/@apollo/client/version.js.map +0 -1
- package/dist/node_modules/@wry/caches/lib/weak.js.map +0 -1
- package/dist/node_modules/@wry/trie/lib/index.js.map +0 -1
- package/dist/node_modules/graphql-ws/dist/client.js.map +0 -1
- package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +0 -11
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +0 -8
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +0 -8
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +0 -6
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +0 -1
- package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +0 -1
- /package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/caching/sizes.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminSubmissionsQueuePage.js","names":[],"sources":["../../src/pages/AdminSubmissionsQueuePage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useCallback, useEffect, useState } from 'react';\nimport { ArrowLeft, Check, X, RefreshCw, PackageCheck, ChevronDown, ChevronUp } from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useNavigate } from 'react-router-dom';\nimport { useStore } from '../providers/StoreProvider';\nimport { formatPriceForModel } from '../utils';\n\ntype PendingProduct = {\n id: string;\n slug: string;\n name: string;\n type: string;\n nature: string;\n status: string;\n pricingModel: string;\n price: number;\n currency: string;\n description?: string | null;\n submittedAt?: string | null;\n submittedBy?: string | null;\n category?: string | null;\n icon?: string | null;\n publisher?: { id: string; name: string; email: string } | null;\n};\n\ntype ProductStatus = 'PENDING_REVIEW' | 'PUBLISHED' | 'REJECTED' | 'ALL';\n\nconst PENDING_PRODUCTS_QUERY = /* GraphQL */ `\n query PendingReviewProducts($limit: Int, $offset: Int) {\n pendingReviewProducts(limit: $limit, offset: $offset) {\n totalCount\n products {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n publisher {\n id\n name\n email\n }\n }\n }\n }\n`;\n\nconst ALL_PRODUCTS_QUERY = /* GraphQL */ `\n query AdminProducts($limit: Int, $offset: Int, $status: ProductStatus) {\n products(filter: { status: $status }, limit: $limit, offset: $offset) {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n publisher {\n id\n name\n email\n }\n }\n }\n`;\n\nconst APPROVE_PRODUCT_MUTATION = /* GraphQL */ `\n mutation ApproveProduct($id: ID!, $notes: String) {\n approveProduct(id: $id, notes: $notes) {\n id\n status\n publishedAt\n }\n }\n`;\n\nconst REJECT_PRODUCT_MUTATION = /* GraphQL */ `\n mutation RejectProduct($id: ID!, $reason: String!) {\n rejectProduct(id: $id, reason: $reason) {\n id\n status\n rejectedReason\n }\n }\n`;\n\nconst STATUS_FILTERS: Array<{ label: string; value: ProductStatus }> = [\n { label: 'Pending review', value: 'PENDING_REVIEW' },\n { label: 'Published', value: 'PUBLISHED' },\n { label: 'Rejected', value: 'REJECTED' },\n { label: 'All', value: 'ALL' },\n];\n\nexport const AdminSubmissionsQueuePage: FC = () => {\n const navigate = useNavigate();\n const { authToken, basePath } = useStore();\n const [products, setProducts] = useState<PendingProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [actingId, setActingId] = useState<string | null>(null);\n const [statusFilter, setStatusFilter] = useState<ProductStatus>('PENDING_REVIEW');\n const [rejectingId, setRejectingId] = useState<string | null>(null);\n const [rejectReason, setRejectReason] = useState('');\n const [viewingId, setViewingId] = useState<string | null>(null);\n\n const loadProducts = useCallback(\n async (filter: ProductStatus) => {\n setLoading(true);\n setError(null);\n try {\n if (filter === 'PENDING_REVIEW') {\n const result = await graphqlFetch<{\n pendingReviewProducts: { totalCount: number; products: PendingProduct[] };\n }>({\n gateway: 'global',\n query: PENDING_PRODUCTS_QUERY,\n variables: { limit: 100, offset: 0 },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load pending products');\n }\n setProducts(result.data?.pendingReviewProducts.products ?? []);\n setTotalCount(result.data?.pendingReviewProducts.totalCount ?? 0);\n } else {\n const result = await graphqlFetch<{ products: PendingProduct[] }>({\n gateway: 'global',\n query: ALL_PRODUCTS_QUERY,\n variables: {\n limit: 100,\n offset: 0,\n ...(filter !== 'ALL' && { status: filter }),\n },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load products');\n }\n const list = result.data?.products ?? [];\n setProducts(list);\n setTotalCount(list.length);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load products');\n } finally {\n setLoading(false);\n }\n },\n [authToken]\n );\n\n useEffect(() => {\n void loadProducts(statusFilter);\n }, [loadProducts, statusFilter]);\n\n const approve = async (id: string) => {\n setActingId(id);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: APPROVE_PRODUCT_MUTATION,\n variables: { id, notes: null },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Approval failed');\n }\n await loadProducts(statusFilter);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Approval failed');\n } finally {\n setActingId(null);\n }\n };\n\n const reject = async (id: string) => {\n if (!rejectReason.trim()) {\n setError('Rejection reason is required');\n return;\n }\n setActingId(id);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: REJECT_PRODUCT_MUTATION,\n variables: { id, reason: rejectReason.trim() },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Rejection failed');\n }\n setRejectingId(null);\n setRejectReason('');\n await loadProducts(statusFilter);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Rejection failed');\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"min-h-screen bg-surface-default\">\n {/* Header */}\n <header className=\"border-b border-border-default bg-surface-raised\">\n <div className=\"mx-auto max-w-7xl px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/dashboard`)}\n className=\"inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n <div className=\"flex items-center gap-2\">\n <PackageCheck className=\"size-5 text-text-primary\" />\n <h1 className=\"text-xl font-semibold text-text-primary\">Submission queue</h1>\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {totalCount}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => void loadProducts(statusFilter)}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary hover:bg-surface-hover\"\n disabled={loading}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n </div>\n\n {/* Status filter pills */}\n <div className=\"mt-4 flex gap-2\">\n {STATUS_FILTERS.map((f) => (\n <button\n key={f.value}\n type=\"button\"\n onClick={() => setStatusFilter(f.value)}\n className={`rounded-full px-3 py-1 text-xs font-medium transition-colors ${\n statusFilter === f.value\n ? 'bg-surface-accent text-text-on-accent'\n : 'bg-surface-muted text-text-secondary hover:bg-surface-hover'\n }`}\n >\n {f.label}\n </button>\n ))}\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-7xl p-6\">\n {error && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n )}\n\n {loading && products.length === 0 ? (\n <output className=\"block py-16 text-center text-text-secondary\">\n Loading submissions…\n </output>\n ) : products.length === 0 ? (\n <div className=\"py-16 text-center text-text-secondary\">\n No products matching the current filter.\n </div>\n ) : (\n <ul className=\"space-y-3\">\n {products.map((p) => (\n <li\n key={p.id}\n className=\"overflow-hidden rounded-lg border border-border-default bg-surface-raised\"\n >\n <div className=\"flex items-start gap-4 p-4\">\n {p.icon ? (\n <img\n src={p.icon}\n alt=\"\"\n className=\"size-14 flex-shrink-0 rounded-md object-cover\"\n />\n ) : (\n <div className=\"flex size-14 flex-shrink-0 items-center justify-center rounded-md bg-surface-muted text-xs text-text-secondary\">\n {p.type}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">\n {p.name}\n </h3>\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {p.type}\n </span>\n <span className=\"rounded-full bg-surface-muted px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {p.nature}\n </span>\n </div>\n <div className=\"mt-0.5 text-xs text-text-tertiary\">{p.slug}</div>\n <div className=\"mt-1 flex items-center gap-3 text-xs text-text-secondary\">\n <span>Publisher: {p.publisher?.name ?? 'Unknown'}</span>\n <span>Price: {formatPriceForModel(p.price, p.currency, p.pricingModel)}</span>\n {p.submittedAt && (\n <span>Submitted {new Date(p.submittedAt).toLocaleString()}</span>\n )}\n </div>\n {p.description && (\n <p className=\"mt-2 line-clamp-2 text-sm text-text-secondary\">\n {p.description}\n </p>\n )}\n </div>\n <div className=\"flex flex-shrink-0 flex-col gap-2\">\n <button\n type=\"button\"\n onClick={() => setViewingId(viewingId === p.id ? null : p.id)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-xs text-text-secondary hover:bg-surface-hover\"\n >\n {viewingId === p.id ? (\n <ChevronUp className=\"size-3.5\" />\n ) : (\n <ChevronDown className=\"size-3.5\" />\n )}\n Details\n </button>\n <button\n type=\"button\"\n onClick={() => void approve(p.id)}\n disabled={actingId === p.id}\n className=\"inline-flex items-center gap-1 rounded-md bg-surface-success px-3 py-1.5 text-xs font-medium text-text-on-success hover:bg-surface-success-hover disabled:opacity-60\"\n >\n <Check className=\"size-3.5\" />\n Approve\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setRejectingId(p.id);\n setRejectReason('');\n }}\n disabled={actingId === p.id}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-danger bg-surface-danger-muted px-3 py-1.5 text-xs font-medium text-text-danger hover:bg-surface-danger hover:text-text-on-danger disabled:opacity-60\"\n >\n <X className=\"size-3.5\" />\n Reject\n </button>\n </div>\n </div>\n\n {viewingId === p.id && (\n <div className=\"border-t border-border-default bg-surface-muted p-4\">\n <dl className=\"grid grid-cols-2 gap-x-6 gap-y-3 text-xs sm:grid-cols-3\">\n <div>\n <dt className=\"font-medium text-text-secondary\">Slug</dt>\n <dd className=\"mt-0.5 font-mono text-text-primary\">{p.slug}</dd>\n </div>\n <div>\n <dt className=\"font-medium text-text-secondary\">Type</dt>\n <dd className=\"mt-0.5 text-text-primary\">{p.type}</dd>\n </div>\n <div>\n <dt className=\"font-medium text-text-secondary\">Nature</dt>\n <dd className=\"mt-0.5 text-text-primary\">{p.nature}</dd>\n </div>\n {p.category && (\n <div>\n <dt className=\"font-medium text-text-secondary\">Category</dt>\n <dd className=\"mt-0.5 text-text-primary\">{p.category}</dd>\n </div>\n )}\n <div>\n <dt className=\"font-medium text-text-secondary\">Pricing</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {formatPriceForModel(p.price, p.currency, p.pricingModel)}{' '}\n <span className=\"text-text-tertiary\">({p.pricingModel})</span>\n </dd>\n </div>\n <div>\n <dt className=\"font-medium text-text-secondary\">Publisher</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {p.publisher?.name ?? '—'}\n {p.publisher?.email && (\n <span className=\"block text-text-tertiary\">{p.publisher.email}</span>\n )}\n </dd>\n </div>\n {p.submittedBy && (\n <div>\n <dt className=\"font-medium text-text-secondary\">Submitted by</dt>\n <dd className=\"mt-0.5 font-mono text-text-primary\">{p.submittedBy}</dd>\n </div>\n )}\n {p.submittedAt && (\n <div>\n <dt className=\"font-medium text-text-secondary\">Submitted at</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {new Date(p.submittedAt).toLocaleString()}\n </dd>\n </div>\n )}\n {p.description && (\n <div className=\"col-span-2 sm:col-span-3\">\n <dt className=\"font-medium text-text-secondary\">Description</dt>\n <dd className=\"mt-0.5 whitespace-pre-wrap text-text-primary\">\n {p.description}\n </dd>\n </div>\n )}\n </dl>\n </div>\n )}\n\n {rejectingId === p.id && (\n <div className=\"border-t border-border-default bg-surface-muted px-4 py-3\">\n <label\n htmlFor={`reject-reason-${p.id}`}\n className=\"block text-xs font-medium text-text-secondary\"\n >\n Rejection reason (required)\n </label>\n <textarea\n id={`reject-reason-${p.id}`}\n aria-label=\"Rejection reason\"\n value={rejectReason}\n onChange={(e) => setRejectReason(e.target.value)}\n rows={3}\n required\n aria-required=\"true\"\n className=\"mt-1 w-full rounded-md border border-border-default bg-surface-default px-3 py-2 text-sm text-text-primary focus:border-border-accent focus:outline-none\"\n placeholder=\"Explain why this submission is being rejected…\"\n />\n <div className=\"mt-2 flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n setRejectingId(null);\n setRejectReason('');\n }}\n className=\"rounded-md border border-border-default bg-surface-default px-3 py-1 text-xs text-text-primary hover:bg-surface-hover\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => void reject(p.id)}\n disabled={!rejectReason.trim() || actingId === p.id}\n className=\"rounded-md bg-surface-danger px-3 py-1 text-xs font-medium text-text-on-danger hover:bg-surface-danger-hover disabled:opacity-60\"\n >\n Submit rejection\n </button>\n </div>\n </div>\n )}\n </li>\n ))}\n </ul>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AdminSubmissionsQueuePage.js","names":[],"sources":["../../src/pages/AdminSubmissionsQueuePage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useCallback, useEffect, useState } from 'react';\nimport { ArrowLeft, Check, X, RefreshCw, PackageCheck, ChevronDown, ChevronUp, ExternalLink } from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useNavigate } from 'react-router-dom';\nimport { useStore } from '../providers/StoreProvider';\nimport { formatPriceForModel } from '../utils';\n\ntype PendingProduct = {\n id: string;\n slug: string;\n name: string;\n type: string;\n nature: string;\n status: string;\n pricingModel: string;\n price: number;\n currency: string;\n description?: string | null;\n submittedAt?: string | null;\n submittedBy?: string | null;\n category?: string | null;\n icon?: string | null;\n productId?: string | null;\n publisher?: { id: string; name: string; email: string } | null;\n};\n\ntype ProductStatus = 'PENDING_REVIEW' | 'PUBLISHED' | 'REJECTED' | 'ALL';\n\nconst PENDING_PRODUCTS_QUERY = /* GraphQL */ `\n query PendingReviewProducts($limit: Int, $offset: Int) {\n pendingReviewProducts(limit: $limit, offset: $offset) {\n totalCount\n products {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n publisher {\n id\n name\n email\n }\n }\n }\n }\n`;\n\nconst ALL_PRODUCTS_QUERY = /* GraphQL */ `\n query AdminProducts($limit: Int, $offset: Int, $status: ProductStatus) {\n products(filter: { status: $status }, limit: $limit, offset: $offset) {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n publisher {\n id\n name\n email\n }\n }\n }\n`;\n\nconst APPROVE_PRODUCT_MUTATION = /* GraphQL */ `\n mutation ApproveProduct($id: ID!, $notes: String) {\n approveProduct(id: $id, notes: $notes) {\n id\n status\n publishedAt\n }\n }\n`;\n\nconst REJECT_PRODUCT_MUTATION = /* GraphQL */ `\n mutation RejectProduct($id: ID!, $reason: String!) {\n rejectProduct(id: $id, reason: $reason) {\n id\n status\n rejectedReason\n }\n }\n`;\n\nconst STATUS_FILTERS: Array<{ label: string; value: ProductStatus }> = [\n { label: 'Pending review', value: 'PENDING_REVIEW' },\n { label: 'Published', value: 'PUBLISHED' },\n { label: 'Rejected', value: 'REJECTED' },\n { label: 'All', value: 'ALL' },\n];\n\nexport const AdminSubmissionsQueuePage: FC = () => {\n const navigate = useNavigate();\n const { authToken, basePath } = useStore();\n const [products, setProducts] = useState<PendingProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [actingId, setActingId] = useState<string | null>(null);\n const [statusFilter, setStatusFilter] = useState<ProductStatus>('PENDING_REVIEW');\n const [rejectingId, setRejectingId] = useState<string | null>(null);\n const [rejectReason, setRejectReason] = useState('');\n const [viewingId, setViewingId] = useState<string | null>(null);\n\n const loadProducts = useCallback(\n async (filter: ProductStatus) => {\n setLoading(true);\n setError(null);\n try {\n if (filter === 'PENDING_REVIEW') {\n const result = await graphqlFetch<{\n pendingReviewProducts: { totalCount: number; products: PendingProduct[] };\n }>({\n gateway: 'global',\n query: PENDING_PRODUCTS_QUERY,\n variables: { limit: 100, offset: 0 },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load pending products');\n }\n setProducts(result.data?.pendingReviewProducts.products ?? []);\n setTotalCount(result.data?.pendingReviewProducts.totalCount ?? 0);\n } else {\n const result = await graphqlFetch<{ products: PendingProduct[] }>({\n gateway: 'global',\n query: ALL_PRODUCTS_QUERY,\n variables: {\n limit: 100,\n offset: 0,\n ...(filter !== 'ALL' && { status: filter }),\n },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load products');\n }\n const list = result.data?.products ?? [];\n setProducts(list);\n setTotalCount(list.length);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load products');\n } finally {\n setLoading(false);\n }\n },\n [authToken]\n );\n\n useEffect(() => {\n void loadProducts(statusFilter);\n }, [loadProducts, statusFilter]);\n\n const approve = async (id: string) => {\n setActingId(id);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: APPROVE_PRODUCT_MUTATION,\n variables: { id, notes: null },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Approval failed');\n }\n await loadProducts(statusFilter);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Approval failed');\n } finally {\n setActingId(null);\n }\n };\n\n const reject = async (id: string) => {\n if (!rejectReason.trim()) {\n setError('Rejection reason is required');\n return;\n }\n setActingId(id);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: REJECT_PRODUCT_MUTATION,\n variables: { id, reason: rejectReason.trim() },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Rejection failed');\n }\n setRejectingId(null);\n setRejectReason('');\n await loadProducts(statusFilter);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Rejection failed');\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"min-h-screen bg-surface-default\">\n {/* Header */}\n <header className=\"border-b border-border-default bg-surface-raised\">\n <div className=\"mx-auto max-w-7xl px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/dashboard`)}\n className=\"inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n <div className=\"flex items-center gap-2\">\n <PackageCheck className=\"size-5 text-text-primary\" />\n <h1 className=\"text-xl font-semibold text-text-primary\">Submission queue</h1>\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {totalCount}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => void loadProducts(statusFilter)}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary hover:bg-surface-hover\"\n disabled={loading}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n </div>\n\n {/* Status filter pills */}\n <div className=\"mt-4 flex gap-2\">\n {STATUS_FILTERS.map((f) => (\n <button\n key={f.value}\n type=\"button\"\n onClick={() => setStatusFilter(f.value)}\n className={`rounded-full px-3 py-1 text-xs font-medium transition-colors ${\n statusFilter === f.value\n ? 'bg-surface-accent text-text-on-accent'\n : 'bg-surface-muted text-text-secondary hover:bg-surface-hover'\n }`}\n >\n {f.label}\n </button>\n ))}\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-7xl p-6\">\n {error && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n )}\n\n {loading && products.length === 0 ? (\n <output className=\"block py-16 text-center text-text-secondary\">\n Loading submissions…\n </output>\n ) : products.length === 0 ? (\n <div className=\"py-16 text-center text-text-secondary\">\n No products matching the current filter.\n </div>\n ) : (\n <ul className=\"space-y-3\">\n {products.map((p) => (\n <li\n key={p.id}\n className=\"overflow-hidden rounded-lg border border-border-default bg-surface-raised\"\n >\n <div className=\"flex items-start gap-4 p-4\">\n {p.icon ? (\n <img\n src={p.icon}\n alt=\"\"\n className=\"size-14 flex-shrink-0 rounded-md object-cover\"\n />\n ) : (\n <div className=\"flex size-14 flex-shrink-0 items-center justify-center rounded-md bg-surface-muted text-xs text-text-secondary\">\n {p.type}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">\n {p.name}\n </h3>\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {p.type}\n </span>\n <span className=\"rounded-full bg-surface-muted px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {p.nature}\n </span>\n </div>\n <div className=\"mt-0.5 text-xs text-text-tertiary\">{p.slug}</div>\n <div className=\"mt-1 flex items-center gap-3 text-xs text-text-secondary\">\n <span>Publisher: {p.publisher?.name ?? 'Unknown'}</span>\n <span>Price: {formatPriceForModel(p.price, p.currency, p.pricingModel)}</span>\n {p.submittedAt && (\n <span>Submitted {new Date(p.submittedAt).toLocaleString()}</span>\n )}\n </div>\n {p.description && (\n <p className=\"mt-2 line-clamp-2 text-sm text-text-secondary\">\n {p.description}\n </p>\n )}\n </div>\n <div className=\"flex flex-shrink-0 flex-col gap-2\">\n {p.productId && (\n <a\n href={`/devportal/apps/${p.productId}`}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-xs text-text-secondary hover:bg-surface-hover\"\n >\n <ExternalLink className=\"size-3.5\" />\n View app\n </a>\n )}\n <button\n type=\"button\"\n onClick={() => setViewingId(viewingId === p.id ? null : p.id)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-xs text-text-secondary hover:bg-surface-hover\"\n >\n {viewingId === p.id ? (\n <ChevronUp className=\"size-3.5\" />\n ) : (\n <ChevronDown className=\"size-3.5\" />\n )}\n Details\n </button>\n <button\n type=\"button\"\n onClick={() => void approve(p.id)}\n disabled={actingId === p.id}\n className=\"inline-flex items-center gap-1 rounded-md bg-surface-success px-3 py-1.5 text-xs font-medium text-text-on-success hover:bg-surface-success-hover disabled:opacity-60\"\n >\n <Check className=\"size-3.5\" />\n Approve\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setRejectingId(p.id);\n setRejectReason('');\n }}\n disabled={actingId === p.id}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-danger bg-surface-danger-muted px-3 py-1.5 text-xs font-medium text-text-danger hover:bg-surface-danger hover:text-text-on-danger disabled:opacity-60\"\n >\n <X className=\"size-3.5\" />\n Reject\n </button>\n </div>\n </div>\n\n {viewingId === p.id && (\n <div className=\"border-t border-border-default bg-surface-muted p-4\">\n <dl className=\"grid grid-cols-2 gap-x-6 gap-y-3 text-xs sm:grid-cols-3\">\n <div>\n <dt className=\"font-medium text-text-secondary\">Slug</dt>\n <dd className=\"mt-0.5 font-mono text-text-primary\">{p.slug}</dd>\n </div>\n <div>\n <dt className=\"font-medium text-text-secondary\">Type</dt>\n <dd className=\"mt-0.5 text-text-primary\">{p.type}</dd>\n </div>\n <div>\n <dt className=\"font-medium text-text-secondary\">Nature</dt>\n <dd className=\"mt-0.5 text-text-primary\">{p.nature}</dd>\n </div>\n {p.category && (\n <div>\n <dt className=\"font-medium text-text-secondary\">Category</dt>\n <dd className=\"mt-0.5 text-text-primary\">{p.category}</dd>\n </div>\n )}\n <div>\n <dt className=\"font-medium text-text-secondary\">Pricing</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {formatPriceForModel(p.price, p.currency, p.pricingModel)}{' '}\n <span className=\"text-text-tertiary\">({p.pricingModel})</span>\n </dd>\n </div>\n <div>\n <dt className=\"font-medium text-text-secondary\">Publisher</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {p.publisher?.name ?? '—'}\n {p.publisher?.email && (\n <span className=\"block text-text-tertiary\">{p.publisher.email}</span>\n )}\n </dd>\n </div>\n {p.productId && (\n <div>\n <dt className=\"font-medium text-text-secondary\">Devportal app ID</dt>\n <dd className=\"mt-0.5 font-mono text-text-primary\">{p.productId}</dd>\n </div>\n )}\n {p.submittedBy && (\n <div>\n <dt className=\"font-medium text-text-secondary\">Submitted by</dt>\n <dd className=\"mt-0.5 font-mono text-text-primary\">{p.submittedBy}</dd>\n </div>\n )}\n {p.submittedAt && (\n <div>\n <dt className=\"font-medium text-text-secondary\">Submitted at</dt>\n <dd className=\"mt-0.5 text-text-primary\">\n {new Date(p.submittedAt).toLocaleString()}\n </dd>\n </div>\n )}\n {p.description && (\n <div className=\"col-span-2 sm:col-span-3\">\n <dt className=\"font-medium text-text-secondary\">Description</dt>\n <dd className=\"mt-0.5 whitespace-pre-wrap text-text-primary\">\n {p.description}\n </dd>\n </div>\n )}\n </dl>\n </div>\n )}\n\n {rejectingId === p.id && (\n <div className=\"border-t border-border-default bg-surface-muted px-4 py-3\">\n <label\n htmlFor={`reject-reason-${p.id}`}\n className=\"block text-xs font-medium text-text-secondary\"\n >\n Rejection reason (required)\n </label>\n <textarea\n id={`reject-reason-${p.id}`}\n aria-label=\"Rejection reason\"\n value={rejectReason}\n onChange={(e) => setRejectReason(e.target.value)}\n rows={3}\n required\n aria-required=\"true\"\n className=\"mt-1 w-full rounded-md border border-border-default bg-surface-default px-3 py-2 text-sm text-text-primary focus:border-border-accent focus:outline-none\"\n placeholder=\"Explain why this submission is being rejected…\"\n />\n <div className=\"mt-2 flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n setRejectingId(null);\n setRejectReason('');\n }}\n className=\"rounded-md border border-border-default bg-surface-default px-3 py-1 text-xs text-text-primary hover:bg-surface-hover\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => void reject(p.id)}\n disabled={!rejectReason.trim() || actingId === p.id}\n className=\"rounded-md bg-surface-danger px-3 py-1 text-xs font-medium text-text-on-danger hover:bg-surface-danger-hover disabled:opacity-60\"\n >\n Submit rejection\n </button>\n </div>\n </div>\n )}\n </li>\n ))}\n </ul>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -5,11 +5,10 @@ import { StoreInstallationStatus as r } from "../generated/global-types.js";
|
|
|
5
5
|
import { useMemo as i, useState as a } from "react";
|
|
6
6
|
import { useI18n as o } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
7
7
|
import { AlertCircle as s, Loader2 as c, Package as l, Plus as u, RefreshCw as d, Trash2 as f } from "lucide-react";
|
|
8
|
-
import {
|
|
9
|
-
import { useNavigate as
|
|
10
|
-
import { AlertDialog as _, AlertDialogAction as v, AlertDialogCancel as y, AlertDialogContent as b, AlertDialogDescription as x, AlertDialogFooter as S, AlertDialogHeader as C, AlertDialogTitle as w } from "@burdenoff/fe-libs/ui";
|
|
8
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
9
|
+
import { useNavigate as h } from "react-router-dom";
|
|
11
10
|
//#region src/pages/InstalledAppsPage.tsx
|
|
12
|
-
var
|
|
11
|
+
var g = [
|
|
13
12
|
{
|
|
14
13
|
label: "All",
|
|
15
14
|
value: "all"
|
|
@@ -38,185 +37,185 @@ var T = [
|
|
|
38
37
|
label: "Uninstalled",
|
|
39
38
|
value: r.Uninstalled
|
|
40
39
|
}
|
|
41
|
-
],
|
|
42
|
-
let
|
|
40
|
+
], _ = (e) => e === r.Active ? "bg-status-success-bg-subtle text-status-success-text" : e === r.Pending || e === r.Installing || e === r.Inactive ? "bg-status-warning-bg-subtle text-status-warning-text" : e === r.Failed ? "bg-status-error-bg-subtle text-status-error-text" : "bg-bg-sunken text-text-muted", v = () => {
|
|
41
|
+
let v = h(), { basePath: y, workspaceId: b } = e(), { t: x } = o(), [S, C] = a("all"), [w, T] = a(null), [E, D] = a(null), { installations: O, totalCount: k, hasMore: A, loading: j, error: M, uninstall: N, uninstallingIds: P, refetch: F, loadMore: I } = n({ filter: i(() => S === "all" ? void 0 : { status: S }, [S]) });
|
|
43
42
|
t({
|
|
44
|
-
variables: { workspaceId:
|
|
45
|
-
skip: !
|
|
43
|
+
variables: { workspaceId: b ?? "" },
|
|
44
|
+
skip: !b,
|
|
46
45
|
onData: () => {
|
|
47
|
-
|
|
46
|
+
F();
|
|
48
47
|
},
|
|
49
48
|
onError: (e) => {
|
|
50
49
|
console.warn("InstallationStatusUpdated subscription error:", e.message);
|
|
51
50
|
}
|
|
52
51
|
});
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
},
|
|
56
|
-
|
|
52
|
+
let L = i(() => [...O].sort((e, t) => t.installedAt.localeCompare(e.installedAt)), [O]), R = () => {
|
|
53
|
+
v(`${y}/marketplace`);
|
|
54
|
+
}, z = async (e) => {
|
|
55
|
+
T(null), await N(e, "User requested uninstall from store UI") || T("Could not uninstall. Try again."), D(null);
|
|
57
56
|
};
|
|
58
|
-
return /* @__PURE__ */
|
|
57
|
+
return /* @__PURE__ */ m("div", {
|
|
59
58
|
className: "flex h-full flex-col",
|
|
60
59
|
children: [
|
|
61
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ p("header", {
|
|
62
61
|
className: "border-b border-border-default bg-bg-surface px-6 py-4",
|
|
63
|
-
children: /* @__PURE__ */
|
|
62
|
+
children: /* @__PURE__ */ m("div", {
|
|
64
63
|
className: "flex items-center justify-between",
|
|
65
|
-
children: [/* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
|
|
66
65
|
className: "text-2xl font-bold text-text-primary",
|
|
67
|
-
children:
|
|
68
|
-
}), /* @__PURE__ */
|
|
66
|
+
children: x("pages.installed.title", { defaultValue: "Installed Apps" })
|
|
67
|
+
}), /* @__PURE__ */ p("p", {
|
|
69
68
|
className: "text-sm text-text-muted",
|
|
70
69
|
children: "Manage your installed applications"
|
|
71
|
-
})] }), /* @__PURE__ */
|
|
70
|
+
})] }), /* @__PURE__ */ m("button", {
|
|
72
71
|
type: "button",
|
|
73
|
-
onClick:
|
|
72
|
+
onClick: R,
|
|
74
73
|
className: "flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 font-semibold text-action-primary-text transition-colors hover:opacity-90",
|
|
75
|
-
children: [/* @__PURE__ */
|
|
74
|
+
children: [/* @__PURE__ */ p(u, { className: "size-5" }), /* @__PURE__ */ p("span", { children: x("pages.installed.installNew", { defaultValue: "Install New App" }) })]
|
|
76
75
|
})]
|
|
77
76
|
})
|
|
78
77
|
}),
|
|
79
|
-
/* @__PURE__ */
|
|
78
|
+
/* @__PURE__ */ p("main", {
|
|
80
79
|
className: "flex-1 overflow-y-auto p-6",
|
|
81
|
-
children: /* @__PURE__ */
|
|
80
|
+
children: /* @__PURE__ */ m("div", {
|
|
82
81
|
className: "mx-auto max-w-6xl",
|
|
83
82
|
children: [
|
|
84
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ m("div", {
|
|
85
84
|
className: "mb-4 flex flex-wrap items-center gap-2",
|
|
86
|
-
children: [
|
|
85
|
+
children: [g.map((e) => /* @__PURE__ */ p("button", {
|
|
87
86
|
type: "button",
|
|
88
|
-
onClick: () =>
|
|
89
|
-
className: `cursor-pointer rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${
|
|
87
|
+
onClick: () => C(e.value),
|
|
88
|
+
className: `cursor-pointer rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${S === e.value ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-primary hover:bg-bg-surface"}`,
|
|
90
89
|
children: e.label
|
|
91
|
-
}, e.label)), /* @__PURE__ */
|
|
90
|
+
}, e.label)), /* @__PURE__ */ m("button", {
|
|
92
91
|
type: "button",
|
|
93
|
-
onClick: () =>
|
|
92
|
+
onClick: () => F(),
|
|
94
93
|
className: "ml-auto cursor-pointer inline-flex items-center gap-2 rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
95
|
-
children: [/* @__PURE__ */
|
|
94
|
+
children: [/* @__PURE__ */ p(d, { className: "size-4" }), "Refresh"]
|
|
96
95
|
})]
|
|
97
96
|
}),
|
|
98
|
-
|
|
97
|
+
w && /* @__PURE__ */ p("div", {
|
|
99
98
|
role: "alert",
|
|
100
99
|
className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text",
|
|
101
|
-
children:
|
|
100
|
+
children: w
|
|
102
101
|
}),
|
|
103
|
-
|
|
102
|
+
j ? /* @__PURE__ */ p("output", {
|
|
104
103
|
"aria-label": "Loading installed apps",
|
|
105
104
|
className: "flex items-center justify-center py-16",
|
|
106
|
-
children: /* @__PURE__ */
|
|
105
|
+
children: /* @__PURE__ */ p(c, {
|
|
107
106
|
className: "size-8 animate-spin text-text-muted",
|
|
108
107
|
"aria-hidden": "true"
|
|
109
108
|
})
|
|
110
|
-
}) :
|
|
109
|
+
}) : M ? /* @__PURE__ */ m("div", {
|
|
111
110
|
role: "alert",
|
|
112
111
|
className: "flex flex-col items-center justify-center rounded-xl border border-status-error-border bg-status-error-bg-subtle py-16 text-center",
|
|
113
112
|
children: [
|
|
114
|
-
/* @__PURE__ */
|
|
115
|
-
/* @__PURE__ */
|
|
113
|
+
/* @__PURE__ */ p(s, { className: "mb-3 size-10 text-status-error-text" }),
|
|
114
|
+
/* @__PURE__ */ p("h3", {
|
|
116
115
|
className: "text-lg font-semibold text-status-error-text",
|
|
117
116
|
children: "Failed to load installations"
|
|
118
117
|
}),
|
|
119
|
-
/* @__PURE__ */
|
|
118
|
+
/* @__PURE__ */ p("p", {
|
|
120
119
|
className: "mt-2 text-sm text-text-muted",
|
|
121
|
-
children:
|
|
120
|
+
children: M.message
|
|
122
121
|
}),
|
|
123
|
-
/* @__PURE__ */
|
|
122
|
+
/* @__PURE__ */ p("button", {
|
|
124
123
|
type: "button",
|
|
125
|
-
onClick: () =>
|
|
124
|
+
onClick: () => F(),
|
|
126
125
|
className: "mt-4 cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text",
|
|
127
126
|
children: "Try Again"
|
|
128
127
|
})
|
|
129
128
|
]
|
|
130
|
-
}) :
|
|
129
|
+
}) : L.length === 0 ? /* @__PURE__ */ p("div", {
|
|
131
130
|
className: "flex items-center justify-center py-16",
|
|
132
|
-
children: /* @__PURE__ */
|
|
131
|
+
children: /* @__PURE__ */ m("div", {
|
|
133
132
|
className: "text-center",
|
|
134
133
|
children: [
|
|
135
|
-
/* @__PURE__ */
|
|
136
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ p(l, { className: "mx-auto mb-4 size-16 text-text-muted" }),
|
|
135
|
+
/* @__PURE__ */ p("h3", {
|
|
137
136
|
className: "mb-2 text-lg font-semibold text-text-primary",
|
|
138
137
|
children: "No apps installed"
|
|
139
138
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
139
|
+
/* @__PURE__ */ p("p", {
|
|
141
140
|
className: "mb-4 text-sm text-text-muted",
|
|
142
141
|
children: "Browse the marketplace to install your first app"
|
|
143
142
|
}),
|
|
144
|
-
/* @__PURE__ */
|
|
143
|
+
/* @__PURE__ */ p("button", {
|
|
145
144
|
type: "button",
|
|
146
|
-
onClick:
|
|
145
|
+
onClick: R,
|
|
147
146
|
className: "rounded-lg bg-action-primary-bg px-4 py-2 font-semibold text-action-primary-text transition-colors hover:opacity-90",
|
|
148
147
|
children: "Browse Marketplace"
|
|
149
148
|
})
|
|
150
149
|
]
|
|
151
150
|
})
|
|
152
|
-
}) : /* @__PURE__ */
|
|
151
|
+
}) : /* @__PURE__ */ m("div", {
|
|
153
152
|
className: "flex flex-col gap-y-4",
|
|
154
153
|
children: [
|
|
155
|
-
/* @__PURE__ */
|
|
154
|
+
/* @__PURE__ */ m("p", {
|
|
156
155
|
"aria-live": "polite",
|
|
157
156
|
className: "text-sm text-text-muted",
|
|
158
157
|
children: [
|
|
159
|
-
|
|
158
|
+
k,
|
|
160
159
|
" installation",
|
|
161
|
-
|
|
160
|
+
k === 1 ? "" : "s",
|
|
162
161
|
" found"
|
|
163
162
|
]
|
|
164
163
|
}),
|
|
165
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ p("ul", {
|
|
166
165
|
className: "flex flex-col gap-y-4",
|
|
167
|
-
children:
|
|
168
|
-
let t =
|
|
169
|
-
return /* @__PURE__ */
|
|
166
|
+
children: L.map((e) => {
|
|
167
|
+
let t = P.has(`${e.workspaceId}:${e.productId}`);
|
|
168
|
+
return /* @__PURE__ */ p("li", {
|
|
170
169
|
className: "rounded-xl border border-border-default bg-bg-surface p-4",
|
|
171
|
-
children: /* @__PURE__ */
|
|
170
|
+
children: /* @__PURE__ */ m("div", {
|
|
172
171
|
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
173
|
-
children: [/* @__PURE__ */
|
|
172
|
+
children: [/* @__PURE__ */ m("div", {
|
|
174
173
|
className: "flex items-start gap-3",
|
|
175
|
-
children: [/* @__PURE__ */
|
|
174
|
+
children: [/* @__PURE__ */ p("div", {
|
|
176
175
|
className: "flex size-12 items-center justify-center rounded-lg bg-bg-sunken text-lg font-semibold text-text-muted",
|
|
177
|
-
children: /* @__PURE__ */
|
|
178
|
-
}), /* @__PURE__ */
|
|
179
|
-
/* @__PURE__ */
|
|
176
|
+
children: /* @__PURE__ */ p(l, { className: "size-6" })
|
|
177
|
+
}), /* @__PURE__ */ m("div", { children: [
|
|
178
|
+
/* @__PURE__ */ p("h3", {
|
|
180
179
|
className: "font-semibold text-text-primary",
|
|
181
180
|
children: e.workspaceName ?? e.workspaceId
|
|
182
181
|
}),
|
|
183
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ m("p", {
|
|
184
183
|
className: "text-sm text-text-muted",
|
|
185
184
|
children: ["Product: ", e.productId]
|
|
186
185
|
}),
|
|
187
|
-
/* @__PURE__ */
|
|
186
|
+
/* @__PURE__ */ m("div", {
|
|
188
187
|
className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-text-muted",
|
|
189
188
|
children: [
|
|
190
|
-
/* @__PURE__ */
|
|
191
|
-
className: `rounded-full px-2 py-1 font-medium ${
|
|
189
|
+
/* @__PURE__ */ p("span", {
|
|
190
|
+
className: `rounded-full px-2 py-1 font-medium ${_(e.status)}`,
|
|
192
191
|
children: e.status
|
|
193
192
|
}),
|
|
194
|
-
e.version && /* @__PURE__ */
|
|
195
|
-
e.workspaceType && /* @__PURE__ */
|
|
193
|
+
e.version && /* @__PURE__ */ m("span", { children: ["v", e.version] }),
|
|
194
|
+
e.workspaceType && /* @__PURE__ */ p("span", { children: e.workspaceType })
|
|
196
195
|
]
|
|
197
196
|
})
|
|
198
197
|
] })]
|
|
199
|
-
}), /* @__PURE__ */
|
|
198
|
+
}), /* @__PURE__ */ m("div", {
|
|
200
199
|
className: "flex items-center gap-2",
|
|
201
200
|
children: [
|
|
202
|
-
/* @__PURE__ */
|
|
201
|
+
/* @__PURE__ */ p("button", {
|
|
203
202
|
type: "button",
|
|
204
|
-
onClick: () =>
|
|
203
|
+
onClick: () => v(`${y}/installed/${e.id}`),
|
|
205
204
|
className: "cursor-pointer rounded-lg border border-border-default px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
206
205
|
children: "Details"
|
|
207
206
|
}),
|
|
208
|
-
/* @__PURE__ */
|
|
207
|
+
/* @__PURE__ */ p("button", {
|
|
209
208
|
type: "button",
|
|
210
|
-
onClick: () =>
|
|
209
|
+
onClick: () => v(`${y}/marketplace/product/${e.productId}`),
|
|
211
210
|
className: "cursor-pointer rounded-lg border border-border-default px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
212
211
|
children: "View Product"
|
|
213
212
|
}),
|
|
214
|
-
e.status !== r.Uninstalled && /* @__PURE__ */
|
|
213
|
+
e.status !== r.Uninstalled && /* @__PURE__ */ m("button", {
|
|
215
214
|
type: "button",
|
|
216
|
-
onClick: () =>
|
|
215
|
+
onClick: () => D(e),
|
|
217
216
|
disabled: t,
|
|
218
217
|
className: "cursor-pointer inline-flex items-center gap-1.5 rounded-lg border border-status-error-border px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:opacity-60",
|
|
219
|
-
children: [t ? /* @__PURE__ */
|
|
218
|
+
children: [t ? /* @__PURE__ */ p(c, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p(f, { className: "size-4" }), "Uninstall"]
|
|
220
219
|
})
|
|
221
220
|
]
|
|
222
221
|
})]
|
|
@@ -224,14 +223,14 @@ var T = [
|
|
|
224
223
|
}, e.id);
|
|
225
224
|
})
|
|
226
225
|
}),
|
|
227
|
-
|
|
226
|
+
A && /* @__PURE__ */ p("div", {
|
|
228
227
|
className: "flex justify-center pt-6",
|
|
229
|
-
children: /* @__PURE__ */
|
|
228
|
+
children: /* @__PURE__ */ p("button", {
|
|
230
229
|
type: "button",
|
|
231
|
-
onClick:
|
|
232
|
-
disabled:
|
|
230
|
+
onClick: I,
|
|
231
|
+
disabled: j,
|
|
233
232
|
className: "rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-subtle disabled:opacity-50",
|
|
234
|
-
children:
|
|
233
|
+
children: j ? "Loading…" : "Load more"
|
|
235
234
|
})
|
|
236
235
|
})
|
|
237
236
|
]
|
|
@@ -239,40 +238,64 @@ var T = [
|
|
|
239
238
|
]
|
|
240
239
|
})
|
|
241
240
|
}),
|
|
242
|
-
/* @__PURE__ */ m(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
241
|
+
E && /* @__PURE__ */ m("div", {
|
|
242
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4",
|
|
243
|
+
children: [/* @__PURE__ */ p("button", {
|
|
244
|
+
type: "button",
|
|
245
|
+
"aria-label": "Cancel uninstall",
|
|
246
|
+
className: "absolute inset-0 bg-bg-overlay/50",
|
|
247
|
+
onClick: () => D(null)
|
|
248
|
+
}), /* @__PURE__ */ m("dialog", {
|
|
249
|
+
open: !0,
|
|
250
|
+
"aria-modal": "true",
|
|
251
|
+
"aria-labelledby": "installed-apps-uninstall-title",
|
|
252
|
+
className: "relative z-10 w-full max-w-md rounded-2xl border border-border-default bg-bg-surface p-6 shadow-2xl",
|
|
253
|
+
children: [
|
|
254
|
+
/* @__PURE__ */ p("h2", {
|
|
255
|
+
id: "installed-apps-uninstall-title",
|
|
256
|
+
className: "text-lg font-semibold text-text-primary",
|
|
257
|
+
children: "Uninstall app"
|
|
253
258
|
}),
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
259
|
+
/* @__PURE__ */ m("p", {
|
|
260
|
+
className: "mt-2 text-sm text-text-muted",
|
|
261
|
+
children: [
|
|
262
|
+
"Remove product",
|
|
263
|
+
" ",
|
|
264
|
+
/* @__PURE__ */ p("span", {
|
|
265
|
+
className: "font-medium text-text-primary",
|
|
266
|
+
children: E.productId
|
|
267
|
+
}),
|
|
268
|
+
" ",
|
|
269
|
+
"from workspace",
|
|
270
|
+
" ",
|
|
271
|
+
/* @__PURE__ */ p("span", {
|
|
272
|
+
className: "font-medium text-text-primary",
|
|
273
|
+
children: E.workspaceName ?? E.workspaceId
|
|
274
|
+
}),
|
|
275
|
+
"?"
|
|
276
|
+
]
|
|
260
277
|
}),
|
|
261
|
-
"
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
278
|
+
/* @__PURE__ */ m("div", {
|
|
279
|
+
className: "mt-6 flex flex-wrap justify-end gap-3",
|
|
280
|
+
children: [/* @__PURE__ */ p("button", {
|
|
281
|
+
type: "button",
|
|
282
|
+
onClick: () => D(null),
|
|
283
|
+
className: "cursor-pointer rounded-lg border border-border-default px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
284
|
+
children: "Cancel"
|
|
285
|
+
}), /* @__PURE__ */ p("button", {
|
|
286
|
+
type: "button",
|
|
287
|
+
onClick: () => z(E),
|
|
288
|
+
className: "cursor-pointer rounded-lg bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-emphasis",
|
|
289
|
+
children: "Uninstall"
|
|
290
|
+
})]
|
|
291
|
+
})
|
|
292
|
+
]
|
|
293
|
+
})]
|
|
271
294
|
})
|
|
272
295
|
]
|
|
273
296
|
});
|
|
274
297
|
};
|
|
275
298
|
//#endregion
|
|
276
|
-
export {
|
|
299
|
+
export { v as InstalledAppsPage };
|
|
277
300
|
|
|
278
301
|
//# sourceMappingURL=InstalledAppsPage.js.map
|