From d9a9ae14fd5010eb336d24f27e191d586c9418d3 Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Thu, 13 Aug 2026 14:54:09 -0400 Subject: [PATCH] various ui improvements --- messages/en-US.json | 16 +-- .../settings/ai-providers/create/page.tsx | 32 ++++- .../public/ProxyResourceTargetsForm.tsx | 14 +- src/components/AiProviderModelListEditor.tsx | 120 ++++++++---------- .../PolicyAuthStackSectionEdit.tsx | 1 - .../resource-target-address-item.tsx | 2 + 6 files changed, 102 insertions(+), 83 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index 25a94eb32..137440d42 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -864,9 +864,9 @@ "policyAuthMethodOff": "Off", "policyAuthSsoTitle": "Platform SSO", "policyAuthSsoDescription": "Require sign-in through your organization's identity provider", - "policyAuthInferenceSsoDescription": "Selected users and roles can authenticate to the gateway using their identity API key", - "policyAuthInferenceIdentityKeyHelp": "Every user already has an identity API key, so you only need to create virtual API keys for non-user clients or shared access. Users can retrieve their key by signing in with their identity provider at , where it will be shown after login.", + "policyAuthInferenceSsoDescription": "Selected users and roles can authenticate to the gateway using their identity API key.", "policyAuthInferenceIdentityKeyHelpNoUrl": "Every user already has an identity API key, so you only need to create virtual API keys for non-user clients or shared access. Users can retrieve their key by signing in with their identity provider at this resource's URL, where it will be shown after login.", + "policyAuthInferenceIdentityKeyHelp": "Every user already has an identity API key, so you only need to create virtual API keys for non-user clients or shared access. Users can retrieve their key by signing in with their identity provider at , where it will be shown after login.", "policyAuthSsoSummary": "{idp} ยท {users} users, {roles} roles", "policyAuthSsoDefaultIdp": "Default provider", "policyAuthAddDefaultIdentityProvider": "Add Default Identity Provider", @@ -1821,7 +1821,7 @@ "aiProviderBudgetUnitUsd": "USD", "aiProviderBudgetUnitTokens": "Tokens", "aiProviderEnabled": "Enabled", - "aiProviderEnabledDescription": "Disable to stop using this provider without deleting it", + "aiProviderEnabledDescription": "Fully disable this provider across all resources", "aiProviderErrorCreate": "Failed to create AI provider", "aiProviderErrorUpdate": "Failed to update AI provider", "aiProviderErrorDelete": "Failed to delete AI provider", @@ -1868,11 +1868,11 @@ "aiProviderModelsAllow": "Allow List", "aiProviderModelsAllowDescription": "Models that may be used through this provider. Empty means deny all.", "aiProviderModelsAllowPlaceholder": "Enter model key", - "aiProviderModelsAllowEmpty": "No models allowed. All requests will be denied.", + "aiProviderModelsAllowEmpty": "No models added yet.", "aiProviderModelsBlock": "Block List", "aiProviderModelsBlockDescription": "Models to deny even if they match an allow entry.", "aiProviderModelsBlockPlaceholder": "Enter model key", - "aiProviderModelsBlockEmpty": "No blocked models.", + "aiProviderModelsBlockEmpty": "No models added yet.", "aiProviderModelsAdd": "Add Models", "aiProviderModelsClearAll": "Clear All", "aiProviderModelsAddCustom": "Add \"{key}\"", @@ -1938,7 +1938,7 @@ "aiResourceProviderAllowModelsEmpty": "No models found", "aiResourceProviderAllowModelsHelp": "Only models from this provider's allow list can be selected.", "aiResourceAliasRequired": "Alias is required for inference resources", - "aiResourceDomainConfiguration": "Domain configuration", + "aiResourceDomainConfiguration": "Domain Configuration", "aiResourceDomainConfigurationDescription": "Choose the domain clients will use to reach this inference resource.", "aiUsageAnalyticsTitle": "AI Usage Analytics", "aiUsageAnalyticsDescription": "Analyze AI gateway cost, token usage, and activity across providers, resources, roles, and users", @@ -3720,9 +3720,9 @@ "internalResourceFormMultiSiteRoutingHelp": "Selecting multiple sites enables resilient routing and failover for high availability.", "internalResourceFormMultiSiteRoutingHelpLearnMore": "Learn more", "editInternalResourceDialogPortRestrictionsDescription": "Restrict access to specific TCP/UDP ports or allow/block all ports.", - "createInternalResourceDialogHttpConfiguration": "HTTP configuration", + "createInternalResourceDialogHttpConfiguration": "Domain Configuration", "createInternalResourceDialogHttpConfigurationDescription": "Choose the domain clients will use to reach this resource over HTTP or HTTPS.", - "editInternalResourceDialogHttpConfiguration": "HTTP configuration", + "editInternalResourceDialogHttpConfiguration": "Domain Configuration", "editInternalResourceDialogHttpConfigurationDescription": "Choose the domain clients will use to reach this resource over HTTP or HTTPS.", "editInternalResourceDialogTcp": "TCP", "editInternalResourceDialogUdp": "UDP", diff --git a/src/app/[orgId]/settings/ai-providers/create/page.tsx b/src/app/[orgId]/settings/ai-providers/create/page.tsx index c9125659d..722874028 100644 --- a/src/app/[orgId]/settings/ai-providers/create/page.tsx +++ b/src/app/[orgId]/settings/ai-providers/create/page.tsx @@ -271,14 +271,14 @@ export default function CreateAiProviderPage() { value ) ); + const currentName = + form.getValues( + "name" + ); if ( value !== "custom" ) { - const currentName = - form.getValues( - "name" - ); const previousLabel = t( aiProviderTypeLabelMap[ @@ -305,6 +305,30 @@ export default function CreateAiProviderPage() { ); targetsRef.current = []; + } else { + const isDefaultName = + Object.entries( + aiProviderTypeLabelMap + ).some( + ([ + type, + key + ]) => + type !== + "custom" && + currentName === + t( + key + ) + ); + if ( + isDefaultName + ) { + form.setValue( + "name", + "" + ); + } } }} /> diff --git a/src/app/[orgId]/settings/resources/public/ProxyResourceTargetsForm.tsx b/src/app/[orgId]/settings/resources/public/ProxyResourceTargetsForm.tsx index 1440e6c02..2cc33acaf 100644 --- a/src/app/[orgId]/settings/resources/public/ProxyResourceTargetsForm.tsx +++ b/src/app/[orgId]/settings/resources/public/ProxyResourceTargetsForm.tsx @@ -86,6 +86,13 @@ export type ProxyResourceTargetsFormHandle = { save: (options?: { silent?: boolean }) => Promise; }; +const DEFAULT_ALLOWED_METHODS: ("http" | "https" | "h2c")[] = [ + "http", + "https", + "h2c" +]; +const EMPTY_TARGETS: LocalTarget[] = []; + type ProxyResourceTargetsFormProps = { orgId: string; isHttp: boolean; @@ -115,12 +122,12 @@ export const ProxyResourceTargetsForm = forwardRef< { orgId, isHttp, - initialTargets = [], + initialTargets = EMPTY_TARGETS, resource, providerId, updateResource, onChange, - allowedMethods = ["http", "https", "h2c"], + allowedMethods = DEFAULT_ALLOWED_METHODS, emptyMessage, embedded = false, hideSaveButton = false, @@ -266,7 +273,7 @@ export const ProxyResourceTargetsForm = forwardRef< ); }); }, - [sites] + [] ); const openHealthCheckDialog = useCallback((target: LocalTarget) => { @@ -616,7 +623,6 @@ export const ProxyResourceTargetsForm = forwardRef< }, [ isAdvancedMode, isHttp, - sites, updateTarget, getDockerStateForSite, refreshContainersForSite, diff --git a/src/components/AiProviderModelListEditor.tsx b/src/components/AiProviderModelListEditor.tsx index 993ef88b8..38014d25f 100644 --- a/src/components/AiProviderModelListEditor.tsx +++ b/src/components/AiProviderModelListEditor.tsx @@ -350,28 +350,24 @@ export function AiProviderModelListEditor({ return (
-
-
-
- {items.length === 0 ? ( -
- - {emptyMessage} - -
- ) : ( - items.map((item) => ( + {items.length === 0 ? ( +

{emptyMessage}

+ ) : ( +
+
+
+ {items.map((item) => ( removeModel(item.clientId)} /> - )) - )} + ))} +
+ {isCollapsed ? ( +
+ ) : null}
{isCollapsed ? ( -
+
+ +
+ ) : null} + {hasOverflow && listExpanded ? ( +
+ +
) : null}
- {isCollapsed ? ( -
- -
- ) : null} - {hasOverflow && listExpanded ? ( -
- -
- ) : null} -
+ )}
( - [] - ); + const [pendingBudgetRows, setPendingBudgetRows] = useState([]); const [attemptedBudgetsSave, setAttemptedBudgetsSave] = useState(false); const [savingBudgets, setSavingBudgets] = useState(false); @@ -929,9 +923,7 @@ function EditModelCredenza({ items={[ { title: t("general"), href: "#" }, { - title: t( - "aiProviderModelsBudgetTab" - ), + title: t("aiProviderModelsBudgetTab"), href: "#" } ]} @@ -970,9 +962,7 @@ function EditModelCredenza({

) : (

- {t( - "aiProviderModelsBudgetUnsaved" - )} + {t("aiProviderModelsBudgetUnsaved")}

)}
diff --git a/src/components/resource-policy/PolicyAuthStackSectionEdit.tsx b/src/components/resource-policy/PolicyAuthStackSectionEdit.tsx index 51b718e88..f6d18b7cf 100644 --- a/src/components/resource-policy/PolicyAuthStackSectionEdit.tsx +++ b/src/components/resource-policy/PolicyAuthStackSectionEdit.tsx @@ -573,7 +573,6 @@ export function PolicyAuthStackSectionEdit({ className="text-primary hover:underline" > {inferenceResourceUrl} - ) } diff --git a/src/components/resource-target-address-item.tsx b/src/components/resource-target-address-item.tsx index 58ef3b33b..79f72369c 100644 --- a/src/components/resource-target-address-item.tsx +++ b/src/components/resource-target-address-item.tsx @@ -142,6 +142,8 @@ export function ResourceTargetAddressItem({ isHttp, allowedMethods = ["http", "https", "h2c"] }: ResourceTargetAddressItemProps) { + "use no memo"; + return (