Improved api key forms + fix non-submittable azure (#2654)

This commit is contained in:
pablodanswer
2024-10-04 19:29:45 -07:00
committed by GitHub
parent 3755e575a5
commit b04e9e9b67
7 changed files with 55 additions and 62 deletions

View File

@@ -16,16 +16,11 @@ import {
SubLabel, SubLabel,
TextArrayField, TextArrayField,
TextFormField, TextFormField,
BooleanFormField,
} from "@/components/admin/connectors/Field"; } from "@/components/admin/connectors/Field";
import { useState } from "react"; import { useState } from "react";
import { Bubble } from "@/components/Bubble";
import { GroupsIcon } from "@/components/icons/icons";
import { useSWRConfig } from "swr"; import { useSWRConfig } from "swr";
import { useUserGroups } from "@/lib/hooks";
import { FullLLMProvider } from "./interfaces"; import { FullLLMProvider } from "./interfaces";
import { PopupSpec } from "@/components/admin/connectors/Popup"; import { PopupSpec } from "@/components/admin/connectors/Popup";
import { usePaidEnterpriseFeaturesEnabled } from "@/components/settings/usePaidEnterpriseFeaturesEnabled";
import * as Yup from "yup"; import * as Yup from "yup";
import isEqual from "lodash/isEqual"; import isEqual from "lodash/isEqual";
import { IsPublicGroupSelector } from "@/components/IsPublicGroupSelector"; import { IsPublicGroupSelector } from "@/components/IsPublicGroupSelector";

View File

@@ -7,21 +7,13 @@ import { LLM_PROVIDERS_ADMIN_URL } from "./constants";
import { import {
SelectorFormField, SelectorFormField,
TextFormField, TextFormField,
BooleanFormField,
MultiSelectField, MultiSelectField,
} from "@/components/admin/connectors/Field"; } from "@/components/admin/connectors/Field";
import { useState } from "react"; import { useState } from "react";
import { Bubble } from "@/components/Bubble";
import { GroupsIcon } from "@/components/icons/icons";
import { useSWRConfig } from "swr"; import { useSWRConfig } from "swr";
import { import { defaultModelsByProvider, getDisplayNameForModel } from "@/lib/hooks";
defaultModelsByProvider,
getDisplayNameForModel,
useUserGroups,
} from "@/lib/hooks";
import { FullLLMProvider, WellKnownLLMProviderDescriptor } from "./interfaces"; import { FullLLMProvider, WellKnownLLMProviderDescriptor } from "./interfaces";
import { PopupSpec } from "@/components/admin/connectors/Popup"; import { PopupSpec } from "@/components/admin/connectors/Popup";
import { usePaidEnterpriseFeaturesEnabled } from "@/components/settings/usePaidEnterpriseFeaturesEnabled";
import * as Yup from "yup"; import * as Yup from "yup";
import isEqual from "lodash/isEqual"; import isEqual from "lodash/isEqual";
import { IsPublicGroupSelector } from "@/components/IsPublicGroupSelector"; import { IsPublicGroupSelector } from "@/components/IsPublicGroupSelector";
@@ -43,11 +35,6 @@ export function LLMProviderUpdateForm({
}) { }) {
const { mutate } = useSWRConfig(); const { mutate } = useSWRConfig();
const isPaidEnterpriseFeaturesEnabled = usePaidEnterpriseFeaturesEnabled();
// EE only
const { data: userGroups, isLoading: userGroupsIsLoading } = useUserGroups();
const [isTesting, setIsTesting] = useState(false); const [isTesting, setIsTesting] = useState(false);
const [testError, setTestError] = useState<string>(""); const [testError, setTestError] = useState<string>("");
@@ -278,7 +265,7 @@ export function LLMProviderUpdateForm({
</div> </div>
))} ))}
{!hideAdvanced && ( {!(hideAdvanced && llmProviderDescriptor.name != "azure") && (
<> <>
<Divider /> <Divider />

View File

@@ -1767,7 +1767,10 @@ export function ChatPage({
<HealthCheckBanner /> <HealthCheckBanner />
{showApiKeyModal && !shouldShowWelcomeModal && ( {showApiKeyModal && !shouldShowWelcomeModal && (
<ApiKeyModal hide={() => setShowApiKeyModal(false)} /> <ApiKeyModal
hide={() => setShowApiKeyModal(false)}
setPopup={setPopup}
/>
)} )}
{/* ChatPopup is a custom popup that displays a admin-specified message on initial user visit. {/* ChatPopup is a custom popup that displays a admin-specified message on initial user visit.

View File

@@ -12,6 +12,8 @@ import { checkLlmProvider } from "./lib";
import { User } from "@/lib/types"; import { User } from "@/lib/types";
import { useProviderStatus } from "@/components/chat_search/ProviderContext"; import { useProviderStatus } from "@/components/chat_search/ProviderContext";
import { usePopup } from "@/components/admin/connectors/Popup";
function setWelcomeFlowComplete() { function setWelcomeFlowComplete() {
Cookies.set(COMPLETED_WELCOME_FLOW_COOKIE, "true", { expires: 365 }); Cookies.set(COMPLETED_WELCOME_FLOW_COOKIE, "true", { expires: 365 });
} }
@@ -28,6 +30,7 @@ export function _WelcomeModal({ user }: { user: User | null }) {
const [providerOptions, setProviderOptions] = useState< const [providerOptions, setProviderOptions] = useState<
WellKnownLLMProviderDescriptor[] WellKnownLLMProviderDescriptor[]
>([]); >([]);
const { popup, setPopup } = usePopup();
const { refreshProviderInfo } = useProviderStatus(); const { refreshProviderInfo } = useProviderStatus();
const clientSetWelcomeFlowComplete = async () => { const clientSetWelcomeFlowComplete = async () => {
@@ -48,34 +51,37 @@ export function _WelcomeModal({ user }: { user: User | null }) {
}, []); }, []);
return ( return (
<Modal title={"Welcome to Danswer!"} width="w-full max-w-3xl"> <>
<div> {popup}
<Text className="mb-4"> <Modal title={"Welcome to Danswer!"} width="w-full max-w-3xl">
Danswer brings all your company&apos;s knowledge to your fingertips, <div>
ready to be accessed instantly. <Text className="mb-4">
</Text> Danswer brings all your company&apos;s knowledge to your fingertips,
<Text className="mb-4"> ready to be accessed instantly.
To get started, we need to set up an API key for the Language Model </Text>
(LLM) provider. This key allows Danswer to interact with the AI model, <Text className="mb-4">
enabling intelligent responses to your queries. To get started, we need to set up an API key for the Language Model
</Text> (LLM) provider. This key allows Danswer to interact with the AI
model, enabling intelligent responses to your queries.
</Text>
<div className="max-h-[900px] overflow-y-scroll"> <div className="max-h-[900px] overflow-y-scroll">
<ApiKeyForm <ApiKeyForm
hidePopup setPopup={setPopup}
onSuccess={() => { onSuccess={() => {
router.refresh(); router.refresh();
refreshProviderInfo(); refreshProviderInfo();
setCanBegin(true); setCanBegin(true);
}} }}
providerOptions={providerOptions} providerOptions={providerOptions}
/> />
</div>
<Divider />
<Button disabled={!canBegin} onClick={clientSetWelcomeFlowComplete}>
Get Started
</Button>
</div> </div>
<Divider /> </Modal>
<Button disabled={!canBegin} onClick={clientSetWelcomeFlowComplete}> </>
Get Started
</Button>
</div>
</Modal>
); );
} }

View File

@@ -1,4 +1,4 @@
import { Popup } from "../admin/connectors/Popup"; import { PopupSpec } from "../admin/connectors/Popup";
import { useState } from "react"; import { useState } from "react";
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from "@tremor/react"; import { TabGroup, TabList, Tab, TabPanels, TabPanel } from "@tremor/react";
import { WellKnownLLMProviderDescriptor } from "@/app/admin/configuration/llm/interfaces"; import { WellKnownLLMProviderDescriptor } from "@/app/admin/configuration/llm/interfaces";
@@ -8,17 +8,12 @@ import { CustomLLMProviderUpdateForm } from "@/app/admin/configuration/llm/Custo
export const ApiKeyForm = ({ export const ApiKeyForm = ({
onSuccess, onSuccess,
providerOptions, providerOptions,
hidePopup, setPopup,
}: { }: {
onSuccess: () => void; onSuccess: () => void;
providerOptions: WellKnownLLMProviderDescriptor[]; providerOptions: WellKnownLLMProviderDescriptor[];
hidePopup?: boolean; setPopup: (popup: PopupSpec) => void;
}) => { }) => {
const [popup, setPopup] = useState<{
message: string;
type: "success" | "error";
} | null>(null);
const defaultProvider = providerOptions[0]?.name; const defaultProvider = providerOptions[0]?.name;
const providerNameToIndexMap = new Map<string, number>(); const providerNameToIndexMap = new Map<string, number>();
providerOptions.forEach((provider, index) => { providerOptions.forEach((provider, index) => {
@@ -35,10 +30,6 @@ export const ApiKeyForm = ({
return ( return (
<div> <div>
{!hidePopup && popup && (
<Popup message={popup.message} type={popup.type} />
)}
<TabGroup <TabGroup
index={providerNameToIndexMap.get(providerName) || 0} index={providerNameToIndexMap.get(providerName) || 0}
onIndexChange={(index) => onIndexChange={(index) =>

View File

@@ -4,8 +4,15 @@ import { ApiKeyForm } from "./ApiKeyForm";
import { Modal } from "../Modal"; import { Modal } from "../Modal";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useProviderStatus } from "../chat_search/ProviderContext"; import { useProviderStatus } from "../chat_search/ProviderContext";
import { PopupSpec } from "../admin/connectors/Popup";
export const ApiKeyModal = ({ hide }: { hide: () => void }) => { export const ApiKeyModal = ({
hide,
setPopup,
}: {
hide: () => void;
setPopup: (popup: PopupSpec) => void;
}) => {
const router = useRouter(); const router = useRouter();
const { const {
@@ -39,6 +46,7 @@ export const ApiKeyModal = ({ hide }: { hide: () => void }) => {
</div> </div>
<ApiKeyForm <ApiKeyForm
setPopup={setPopup}
onSuccess={() => { onSuccess={() => {
router.refresh(); router.refresh();
refreshProviderInfo(); refreshProviderInfo();

View File

@@ -597,7 +597,10 @@ export const SearchSection = ({
{!shouldDisplayNoSources && {!shouldDisplayNoSources &&
showApiKeyModal && showApiKeyModal &&
!shouldShowWelcomeModal && ( !shouldShowWelcomeModal && (
<ApiKeyModal hide={() => setShowApiKeyModal(false)} /> <ApiKeyModal
setPopup={setPopup}
hide={() => setShowApiKeyModal(false)}
/>
)} )}
{deletingChatSession && ( {deletingChatSession && (