import type { Folder } from "@yaakapp-internal/models"; import { modelTypeLabel, patchModel } from "@yaakapp-internal/models"; import { useMemo } from "react"; import { openFolderSettings } from "../commands/openFolderSettings"; import { openWorkspaceSettings } from "../commands/openWorkspaceSettings"; import { Icon } from "../components/core/Icon"; import { IconTooltip } from "../components/core/IconTooltip"; import { InlineCode } from "../components/core/InlineCode"; import { HStack } from "../components/core/Stacks"; import type { TabItem } from "../components/core/Tabs/Tabs"; import { capitalize } from "../lib/capitalize"; import { showConfirm } from "../lib/confirm"; import { resolvedModelName } from "../lib/resolvedModelName"; import { useHttpAuthenticationSummaries } from "./useHttpAuthentication"; import type { AuthenticatedModel } from "./useInheritedAuthentication"; import { useInheritedAuthentication } from "./useInheritedAuthentication"; import { useModelAncestors } from "./useModelAncestors"; export function useAuthTab(tabValue: T, model: AuthenticatedModel | null) { const authentication = useHttpAuthenticationSummaries(); const inheritedAuth = useInheritedAuthentication(model); const ancestors = useModelAncestors(model); const parentModel = ancestors[0] ?? null; return useMemo(() => { if (model == null) return []; const tab: TabItem = { value: tabValue, label: "Auth", options: { value: model.authenticationType, items: [ ...authentication.map((a) => ({ label: a.label || "UNKNOWN", shortLabel: a.shortLabel, value: a.name, })), { type: "separator" }, { label: "Inherit from Parent", shortLabel: inheritedAuth != null && inheritedAuth.authenticationType !== "none" ? ( {authentication.find((a) => a.name === inheritedAuth.authenticationType) ?.shortLabel ?? "UNKNOWN"} ) : ( "Auth" ), value: null, }, { label: "No Auth", shortLabel: "No Auth", value: "none" }, ], itemsAfter: (() => { const actions: ( | { type: "separator"; label: string } | { label: string; leftSlot: React.ReactNode; onSelect: () => Promise } )[] = []; // Promote: move auth from current model up to parent if ( parentModel && model.authenticationType && model.authenticationType !== "none" && (parentModel.authenticationType == null || parentModel.authenticationType === "none") ) { actions.push( { type: "separator", label: "Actions" }, { label: `Promote to ${capitalize(parentModel.model)}`, leftSlot: ( ), onSelect: async () => { const confirmed = await showConfirm({ id: "promote-auth-confirm", title: "Promote Authentication", confirmText: "Promote", description: ( <> Move authentication config to{" "} {resolvedModelName(parentModel)}? ), }); if (confirmed) { await patchModel(model, { authentication: {}, authenticationType: null }); await patchModel(parentModel, { authentication: model.authentication, authenticationType: model.authenticationType, }); if (parentModel.model === "folder") { openFolderSettings(parentModel.id, "auth"); } else { openWorkspaceSettings("auth"); } } }, }, ); } // Copy from ancestor: copy auth config down to current model const ancestorWithAuth = ancestors.find( (a) => a.authenticationType != null && a.authenticationType !== "none", ); if (ancestorWithAuth) { if (actions.length === 0) { actions.push({ type: "separator", label: "Actions" }); } actions.push({ label: `Copy from ${modelTypeLabel(ancestorWithAuth)}`, leftSlot: ( ), onSelect: async () => { const confirmed = await showConfirm({ id: "copy-auth-confirm", title: "Copy Authentication", confirmText: "Copy", description: ( <> Copy{" "} {authentication.find((a) => a.name === ancestorWithAuth.authenticationType) ?.label ?? "authentication"}{" "} config from {resolvedModelName(ancestorWithAuth)}? This will override the current authentication but will not affect the{" "} {modelTypeLabel(ancestorWithAuth).toLowerCase()}. ), }); if (confirmed) { await patchModel(model, { authentication: { ...ancestorWithAuth.authentication }, authenticationType: ancestorWithAuth.authenticationType, }); } }, }); } return actions.length > 0 ? actions : undefined; })(), onChange: async (authenticationType) => { let authentication: Folder["authentication"] = model.authentication; if (model.authenticationType !== authenticationType) { authentication = { // Reset auth if changing types }; } await patchModel(model, { authentication, authenticationType }); }, }, }; return [tab]; }, [authentication, inheritedAuth, model, parentModel, tabValue, ancestors]); }