import React, { useEffect, useState } from "react"; import { X } from "@phosphor-icons/react"; import Workspace from "@/models/workspace"; import { TagsInput } from "react-tag-input-component"; import Embed from "@/models/embed"; export function enforceSubmissionSchema(form) { const data = {}; for (var [key, value] of form.entries()) { if (!value || value === null) continue; data[key] = value; if (value === "on") data[key] = true; } // Always set value on nullable keys since empty or off will not send anything from form element. if (!data.hasOwnProperty("allowlist_domains")) data.allowlist_domains = null; if (!data.hasOwnProperty("allow_model_override")) data.allow_model_override = false; if (!data.hasOwnProperty("allow_temperature_override")) data.allow_temperature_override = false; if (!data.hasOwnProperty("allow_prompt_override")) data.allow_prompt_override = false; if (!data.hasOwnProperty("message_limit")) data.message_limit = 20; return data; } export default function NewEmbedModal({ closeModal }) { const [error, setError] = useState(null); const handleCreate = async (e) => { setError(null); e.preventDefault(); const form = new FormData(e.target); const data = enforceSubmissionSchema(form); const { embed, error } = await Embed.newEmbed(data); if (!!embed) window.location.reload(); setError(error); }; return (

Create new embed for workspace

{error &&

Error: {error}

}

After creating an embed you will be provided a link that you can publish on your website with a simple <script> {" "} tag.

); } export const WorkspaceSelection = ({ defaultValue = null }) => { const [workspaces, setWorkspaces] = useState([]); useEffect(() => { async function fetchWorkspaces() { const _workspaces = await Workspace.all(); setWorkspaces(_workspaces); } fetchWorkspaces(); }, []); return (

This is the workspace your chat window will be based on. All defaults will be inherited from the workspace unless overridden by this config.

); }; export const ChatModeSelection = ({ defaultValue = null }) => { const [chatMode, setChatMode] = useState(defaultValue ?? "query"); return (

Set how your chatbot should operate. Query means it will only respond if a document helps answer the query.
Chat opens the chat to even general questions and can answer totally unrelated queries to your workspace.

); }; export const PermittedDomains = ({ defaultValue = [] }) => { const [domains, setDomains] = useState(defaultValue); const handleChange = (data) => { const validDomains = data .map((input) => { let url = input; if (!url.includes("http://") && !url.includes("https://")) url = `https://${url}`; try { new URL(url); return url; } catch { return null; } }) .filter((u) => !!u); setDomains(validDomains); }; const handleBlur = (event) => { const currentInput = event.target.value; if (!currentInput) return; const validDomains = [...domains, currentInput].map((input) => { let url = input; if (!url.includes("http://") && !url.includes("https://")) url = `https://${url}`; try { new URL(url); return url; } catch { return null; } }); event.target.value = ""; setDomains(validDomains); }; return (

This filter will block any requests that come from a domain other than the list below.
Leaving this empty means anyone can use your embed on any site.

); }; export const NumberInput = ({ name, title, hint, defaultValue = 0 }) => { return (

{hint}

e.target.blur()} />
); }; export const BooleanInput = ({ name, title, hint, defaultValue = null }) => { const [status, setStatus] = useState(defaultValue ?? false); return (

{hint}

); };