misc: removed preview features

This commit is contained in:
Sheen Capadngan
2025-12-16 22:14:15 +08:00
parent 2dcac4fc27
commit 139c346fac
5 changed files with 139 additions and 148 deletions

View File

@@ -27,8 +27,7 @@ import {
MCPEndpointConnectedServersSection,
MCPEndpointConnectionSection,
MCPEndpointDetailsSection,
MCPEndpointToolSelectionSection,
MCPEndpointUsageStatisticsSection
MCPEndpointToolSelectionSection
} from "./components";
const PageContent = () => {
@@ -151,11 +150,6 @@ const PageContent = () => {
{/* Right Column - Usage Statistics & Tool Selection */}
<div className="flex flex-1 flex-col gap-4">
<MCPEndpointUsageStatisticsSection
endpointId={mcpEndpoint.id}
endpointName={mcpEndpoint.name}
projectId={mcpEndpoint.projectId}
/>
<MCPEndpointToolSelectionSection
endpointId={mcpEndpoint.id}
projectId={mcpEndpoint.projectId}

View File

@@ -29,6 +29,8 @@ type AuthToken = {
const STORAGE_KEY_PREFIX = "mcp_endpoint_tokens_";
const SHOW_AUTH_TOKENS_SECTION = false;
export const MCPEndpointConnectionSection = ({ endpoint }: Props) => {
const [isCopied, setIsCopied] = useToggle(false);
const [isCreateModalOpen, setIsCreateModalOpen] = useToggle(false);
@@ -165,78 +167,80 @@ export const MCPEndpointConnectionSection = ({ endpoint }: Props) => {
</div>
</GenericFieldLabel>
<div className="space-y-3 border-t border-mineshaft-500 pt-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2 text-sm text-mineshaft-300">
<FontAwesomeIcon icon={faKey} className="text-xs" />
<span>Authentication Tokens</span>
{SHOW_AUTH_TOKENS_SECTION && (
<div className="space-y-3 border-t border-mineshaft-500 pt-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2 text-sm text-mineshaft-300">
<FontAwesomeIcon icon={faKey} className="text-xs" />
<span>Authentication Tokens</span>
</div>
<Button
variant="outline_bg"
size="xs"
leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={setIsCreateModalOpen.on}
>
Create
</Button>
</div>
<Button
variant="outline_bg"
size="xs"
leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={setIsCreateModalOpen.on}
>
Create
</Button>
</div>
{authTokens.length > 0 && (
<div className="space-y-2">
{authTokens.map((token) => (
<div
key={token.id}
className="flex items-center justify-between rounded border border-mineshaft-600 bg-mineshaft-800 px-3 py-2.5"
>
<div className="min-w-0 flex-1">
<div className="flex items-center justify-between">
<h4 className="truncate text-sm font-medium text-mineshaft-100">
{token.name}
</h4>
<Tooltip content="Delete token">
<IconButton
ariaLabel="Delete token"
variant="plain"
size="xs"
onClick={() => handleDeleteToken(token.id)}
className="text-red-500 hover:text-red-400"
>
<FontAwesomeIcon icon={faTrash} />
</IconButton>
</Tooltip>
</div>
<p className="mt-0.5 text-xs text-mineshaft-400">
Created {formatDate(token.createdAt)}
</p>
<div className="mt-1.5 flex items-center gap-2">
<code className="font-mono text-xs text-mineshaft-300">
{truncateToken(token.token)}
</code>
<Tooltip content={copiedTokenId === token.id ? "Copied!" : "Copy token"}>
<button
type="button"
onClick={() => handleCopyToken(token.token, token.id)}
className="text-mineshaft-400 transition-colors hover:text-mineshaft-200"
>
<FontAwesomeIcon
icon={copiedTokenId === token.id ? faCheck : faCopy}
className="text-xs"
/>
</button>
</Tooltip>
{authTokens.length > 0 && (
<div className="space-y-2">
{authTokens.map((token) => (
<div
key={token.id}
className="flex items-center justify-between rounded border border-mineshaft-600 bg-mineshaft-800 px-3 py-2.5"
>
<div className="min-w-0 flex-1">
<div className="flex items-center justify-between">
<h4 className="truncate text-sm font-medium text-mineshaft-100">
{token.name}
</h4>
<Tooltip content="Delete token">
<IconButton
ariaLabel="Delete token"
variant="plain"
size="xs"
onClick={() => handleDeleteToken(token.id)}
className="text-red-500 hover:text-red-400"
>
<FontAwesomeIcon icon={faTrash} />
</IconButton>
</Tooltip>
</div>
<p className="mt-0.5 text-xs text-mineshaft-400">
Created {formatDate(token.createdAt)}
</p>
<div className="mt-1.5 flex items-center gap-2">
<code className="font-mono text-xs text-mineshaft-300">
{truncateToken(token.token)}
</code>
<Tooltip content={copiedTokenId === token.id ? "Copied!" : "Copy token"}>
<button
type="button"
onClick={() => handleCopyToken(token.token, token.id)}
className="text-mineshaft-400 transition-colors hover:text-mineshaft-200"
>
<FontAwesomeIcon
icon={copiedTokenId === token.id ? faCheck : faCopy}
className="text-xs"
/>
</button>
</Tooltip>
</div>
</div>
</div>
</div>
))}
</div>
)}
))}
</div>
)}
{authTokens.length === 0 && (
<p className="py-2 text-xs text-mineshaft-400 italic">
No authentication tokens created yet
</p>
)}
</div>
{authTokens.length === 0 && (
<p className="py-2 text-xs text-mineshaft-400 italic">
No authentication tokens created yet
</p>
)}
</div>
)}
</div>
</div>

View File

@@ -44,6 +44,8 @@ const getStatusColor = (status: string | null) => {
return colors[status || "inactive"] || "bg-red-500";
};
const SHOW_PII_FILTERING_AND_RATE_LIMITING_SECTION = false;
export const MCPEndpointDetailsSection = ({ endpoint, onEdit }: Props) => {
const updateEndpoint = useUpdateAiMcpEndpoint();
const [rateLimitSettings, setRateLimitSettings] = useState<RateLimitSettings>({
@@ -143,64 +145,67 @@ export const MCPEndpointDetailsSection = ({ endpoint, onEdit }: Props) => {
<GenericFieldLabel label="Created">
{format(new Date(endpoint.createdAt), "yyyy-MM-dd, hh:mm aaa")}
</GenericFieldLabel>
<div className="border-t border-mineshaft-500 pt-3">
<div className="flex items-start justify-between">
<div className="flex flex-col gap-0.5">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-mineshaft-200">PII Filtering</span>
<Tooltip
content="When enabled, personally identifiable information (credit cards, addresses, phone numbers, etc.) will be redacted in requests and responses"
className="max-w-xs"
>
<FontAwesomeIcon
icon={faInfoCircle}
className="cursor-default text-bunker-400 hover:text-bunker-300"
{SHOW_PII_FILTERING_AND_RATE_LIMITING_SECTION && (
<>
<div className="border-t border-mineshaft-500 pt-3">
<div className="flex items-start justify-between">
<div className="flex flex-col gap-0.5">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-mineshaft-200">PII Filtering</span>
<Tooltip
content="When enabled, personally identifiable information (credit cards, addresses, phone numbers, etc.) will be redacted in requests and responses"
className="max-w-xs"
>
<FontAwesomeIcon
icon={faInfoCircle}
className="cursor-default text-bunker-400 hover:text-bunker-300"
/>
</Tooltip>
</div>
<span className="text-xs text-bunker-400">Redact sensitive data</span>
</div>
<Switch
id={`pii-filtering-${endpoint.id}`}
isChecked={endpoint.piiFiltering ?? false}
onCheckedChange={handlePiiFilteringToggle}
isDisabled={updateEndpoint.isPending}
/>
</div>
</div>
<div className="pt-1">
<div className="flex items-start justify-between">
<div className="flex flex-col gap-0.5">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-mineshaft-200">Rate Limiting</span>
</div>
<span className="text-xs text-bunker-400">Limit tool invocations per user</span>
</div>
<Switch
id={`rate-limiting-${endpoint.id}`}
isChecked={rateLimitSettings.enabled}
onCheckedChange={handleRateLimitToggle}
/>
</div>
{rateLimitSettings.enabled && (
<div className="mt-3 grid grid-cols-2 gap-3">
<Input
type="number"
value={rateLimitSettings.limit.toString()}
onChange={(e) => handleRateLimitChange(e.target.value)}
min={1}
placeholder="100"
/>
</Tooltip>
</div>
<span className="text-xs text-bunker-400">Redact sensitive data</span>
<Select value={rateLimitSettings.timeUnit} onValueChange={handleTimeUnitChange}>
<SelectItem value="minute">per minute</SelectItem>
<SelectItem value="hour">per hour</SelectItem>
<SelectItem value="day">per day</SelectItem>
</Select>
</div>
)}
</div>
<Switch
id={`pii-filtering-${endpoint.id}`}
isChecked={endpoint.piiFiltering ?? false}
onCheckedChange={handlePiiFilteringToggle}
isDisabled={updateEndpoint.isPending}
/>
</div>
</div>
<div className="pt-1">
<div className="flex items-start justify-between">
<div className="flex flex-col gap-0.5">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-mineshaft-200">Rate Limiting</span>
</div>
<span className="text-xs text-bunker-400">Limit tool invocations per user</span>
</div>
<Switch
id={`rate-limiting-${endpoint.id}`}
isChecked={rateLimitSettings.enabled}
onCheckedChange={handleRateLimitToggle}
/>
</div>
{rateLimitSettings.enabled && (
<div className="mt-3 grid grid-cols-2 gap-3">
<Input
type="number"
value={rateLimitSettings.limit.toString()}
onChange={(e) => handleRateLimitChange(e.target.value)}
min={1}
placeholder="100"
/>
<Select value={rateLimitSettings.timeUnit} onValueChange={handleTimeUnitChange}>
<SelectItem value="minute">per minute</SelectItem>
<SelectItem value="hour">per hour</SelectItem>
<SelectItem value="day">per day</SelectItem>
</Select>
</div>
)}
</div>
</>
)}
</div>
</div>
);

View File

@@ -2,12 +2,11 @@ import { useMemo } from "react";
import { faChartLine, faTools, faUsers } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useListAiMcpActivityLogs, useListEndpointTools } from "@app/hooks/api";
import { TAiMcpActivityLog, useListEndpointTools } from "@app/hooks/api";
type Props = {
endpointId: string;
endpointName: string;
projectId: string;
};
type StatCardProps = {
@@ -42,14 +41,8 @@ const StatCard = ({ icon, label, value, subtitle, trend }: StatCardProps) => {
);
};
export const MCPEndpointUsageStatisticsSection = ({
endpointId,
endpointName,
projectId
}: Props) => {
const { data: activityLogs = [] } = useListAiMcpActivityLogs({
projectId
});
export const MCPEndpointUsageStatisticsSection = ({ endpointId, endpointName }: Props) => {
const activityLogs: TAiMcpActivityLog[] = [];
const { data: endpointTools = [] } = useListEndpointTools({ endpointId });
const statistics = useMemo(() => {

View File

@@ -1,4 +1,4 @@
import { Button, GenericFieldLabel } from "@app/components/v2";
import { GenericFieldLabel } from "@app/components/v2";
import { AiMcpServerCredentialMode, TAiMcpServer } from "@app/hooks/api";
type Props = {
@@ -14,18 +14,13 @@ const getCredentialModeLabel = (mode: AiMcpServerCredentialMode) => {
};
export const MCPServerCredentialsSection = ({ server }: Props) => {
const handleManageCredentials = () => {
// TODO: Implement credential management modal
// Will handle re-authentication and credential removal
};
return (
<div className="flex w-full flex-col gap-3 rounded-lg border border-mineshaft-600 bg-mineshaft-900 px-4 py-3">
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-2">
<h3 className="text-lg font-medium text-mineshaft-100">Credentials</h3>
<Button variant="outline_bg" size="xs" onClick={handleManageCredentials}>
{/* <Button variant="outline_bg" size="xs" onClick={handleManageCredentials}>
Manage
</Button>
</Button> */}
</div>
<div className="space-y-3">
<GenericFieldLabel label="Credential Mode">