diff --git a/web/src/app/admin/assistants/AssistantEditor.tsx b/web/src/app/admin/assistants/AssistantEditor.tsx
index 1f961614dbc..19ddba86b3c 100644
--- a/web/src/app/admin/assistants/AssistantEditor.tsx
+++ b/web/src/app/admin/assistants/AssistantEditor.tsx
@@ -106,6 +106,7 @@ export function AssistantEditor({
admin?: boolean;
}) {
const router = useRouter();
+
const { popup, setPopup } = usePopup();
const colorOptions = [
diff --git a/web/src/app/admin/configuration/search/page.tsx b/web/src/app/admin/configuration/search/page.tsx
index 6a0d428d357..a66e45d9023 100644
--- a/web/src/app/admin/configuration/search/page.tsx
+++ b/web/src/app/admin/configuration/search/page.tsx
@@ -19,7 +19,9 @@ export interface EmbeddingDetails {
default_model_id?: number;
name: string;
}
+
import { EmbeddingIcon } from "@/components/icons/icons";
+import { usePopupFromQuery } from "@/components/popup/PopupFromQuery";
import Link from "next/link";
import { SavedSearchSettings } from "../../embeddings/interfaces";
@@ -29,6 +31,12 @@ import { SettingsContext } from "@/components/settings/SettingsProvider";
function Main() {
const settings = useContext(SettingsContext);
+ const { popup: searchSettingsPopup } = usePopupFromQuery({
+ "search-settings": {
+ message: `Changed search settings successfully`,
+ type: "success",
+ },
+ });
const {
data: currentEmeddingModel,
isLoading: isLoadingCurrentModel,
@@ -74,6 +82,7 @@ function Main() {
return (
+ {searchSettingsPopup}
{!futureEmbeddingModel ? (
<>
{settings?.settings.needs_reindexing && (
diff --git a/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx b/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx
index 8294b6ca0d0..07b719d8341 100644
--- a/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx
+++ b/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx
@@ -41,7 +41,7 @@ import { Formik } from "formik";
import { AccessTypeForm } from "@/components/admin/connectors/AccessTypeForm";
import { AccessTypeGroupSelector } from "@/components/admin/connectors/AccessTypeGroupSelector";
import NavigationRow from "./NavigationRow";
-
+import { useRouter } from "next/navigation";
export interface AdvancedConfig {
refreshFreq: number;
pruneFreq: number;
@@ -111,6 +111,8 @@ export default function AddConnector({
}: {
connector: ConfigurableSources;
}) {
+ const router = useRouter();
+
// State for managing credentials and files
const [currentCredential, setCurrentCredential] =
useState
| null>(null);
@@ -201,13 +203,7 @@ export default function AddConnector({
};
const onSuccess = () => {
- setPopup({
- message: "Connector created! Redirecting to connector home page",
- type: "success",
- });
- setTimeout(() => {
- window.open("/admin/indexing/status", "_self");
- }, 1000);
+ router.push("/admin/indexing/status?message=connector-created");
};
return (
diff --git a/web/src/app/admin/embeddings/pages/EmbeddingFormPage.tsx b/web/src/app/admin/embeddings/pages/EmbeddingFormPage.tsx
index adf486ed5d4..196c99da0d2 100644
--- a/web/src/app/admin/embeddings/pages/EmbeddingFormPage.tsx
+++ b/web/src/app/admin/embeddings/pages/EmbeddingFormPage.tsx
@@ -25,9 +25,11 @@ import RerankingDetailsForm from "../RerankingFormPage";
import { useEmbeddingFormContext } from "@/components/context/EmbeddingContext";
import { Modal } from "@/components/Modal";
+import { useRouter } from "next/navigation";
export default function EmbeddingForm() {
const { formStep, nextFormStep, prevFormStep } = useEmbeddingFormContext();
const { popup, setPopup } = usePopup();
+ const router = useRouter();
const [advancedEmbeddingDetails, setAdvancedEmbeddingDetails] =
useState({
@@ -172,10 +174,6 @@ export default function EmbeddingForm() {
const response = await updateSearchSettings(values);
if (response.ok) {
- setPopup({
- message: "Updated search settings successfully",
- type: "success",
- });
return true;
} else {
setPopup({ message: "Failed to update search settings", type: "error" });
@@ -184,14 +182,7 @@ export default function EmbeddingForm() {
};
const navigateToEmbeddingPage = (changedResource: string) => {
- setPopup({
- message: `Changed ${changedResource} successfully. Redirecting to embedding page`,
- type: "success",
- });
-
- setTimeout(() => {
- window.open("/admin/configuration/search", "_self");
- }, 2000);
+ router.push("/admin/configuration/search?message=search-settings");
};
const onConfirm = async () => {
diff --git a/web/src/app/admin/indexing/status/page.tsx b/web/src/app/admin/indexing/status/page.tsx
index f5d64d3ac3a..bb56ceaa74e 100644
--- a/web/src/app/admin/indexing/status/page.tsx
+++ b/web/src/app/admin/indexing/status/page.tsx
@@ -11,8 +11,15 @@ import { AdminPageTitle } from "@/components/admin/Title";
import Link from "next/link";
import { Button, Text } from "@tremor/react";
import { useConnectorCredentialIndexingStatus } from "@/lib/hooks";
+import { usePopupFromQuery } from "@/components/popup/PopupFromQuery";
function Main() {
+ const { popup } = usePopupFromQuery({
+ "connector-created": {
+ message: "Connector created successfully",
+ type: "success",
+ },
+ });
const {
data: indexAttemptData,
isLoading: indexAttemptIsLoading,
@@ -67,10 +74,13 @@ function Main() {
});
return (
-
+ <>
+ {popup}
+
+ >
);
}
diff --git a/web/src/components/context/EmbeddingContext.tsx b/web/src/components/context/EmbeddingContext.tsx
index 2ca18dc955e..3d03b99b1d5 100644
--- a/web/src/components/context/EmbeddingContext.tsx
+++ b/web/src/components/context/EmbeddingContext.tsx
@@ -57,9 +57,15 @@ export const EmbeddingFormProvider: React.FC<{
useEffect(() => {
// Update URL when formStep changes
const updatedSearchParams = new URLSearchParams(searchParams.toString());
+ const existingStep = updatedSearchParams.get("step");
updatedSearchParams.set("step", formStep.toString());
const newUrl = `${pathname}?${updatedSearchParams.toString()}`;
- router.push(newUrl);
+
+ if (!existingStep) {
+ router.replace(newUrl);
+ } else if (newUrl !== pathname) {
+ router.push(newUrl);
+ }
}, [formStep, router, pathname, searchParams]);
// Update formStep when URL changes
diff --git a/web/src/components/context/FormContext.tsx b/web/src/components/context/FormContext.tsx
index 8755fbe6da1..d445782f718 100644
--- a/web/src/components/context/FormContext.tsx
+++ b/web/src/components/context/FormContext.tsx
@@ -57,12 +57,17 @@ export const FormProvider: React.FC<{
useEffect(() => {
// Update URL when formStep changes
const updatedSearchParams = new URLSearchParams(searchParams.toString());
+ const existingStep = updatedSearchParams.get("step");
updatedSearchParams.set("step", formStep.toString());
const newUrl = `${pathname}?${updatedSearchParams.toString()}`;
- router.push(newUrl);
+
+ if (!existingStep) {
+ router.replace(newUrl);
+ } else if (newUrl !== pathname) {
+ router.push(newUrl);
+ }
}, [formStep, router, pathname, searchParams]);
- // Update formStep when URL changes
useEffect(() => {
const stepFromUrl = parseInt(searchParams.get("step") || "0", 10);
if (stepFromUrl !== formStep) {
diff --git a/web/src/components/popup/PopupFromQuery.tsx b/web/src/components/popup/PopupFromQuery.tsx
new file mode 100644
index 00000000000..71834f69987
--- /dev/null
+++ b/web/src/components/popup/PopupFromQuery.tsx
@@ -0,0 +1,28 @@
+import { useEffect } from "react";
+
+import { usePopup } from "../admin/connectors/Popup";
+import { PopupSpec } from "../admin/connectors/Popup";
+import { useRouter } from "next/navigation";
+
+interface PopupMessages {
+ [key: string]: PopupSpec;
+}
+
+export const usePopupFromQuery = (messages: PopupMessages) => {
+ const router = useRouter();
+ const { popup, setPopup } = usePopup();
+
+ useEffect(() => {
+ const searchParams = new URLSearchParams(window.location.search);
+ // Get the value for search param with key "message"
+ const messageValue = searchParams.get("message");
+ // Check if any key from messages object is present in search params
+ if (messageValue && messageValue in messages) {
+ const popupMessage = messages[messageValue];
+ router.replace(window.location.pathname);
+ setPopup(popupMessage);
+ }
+ }, []);
+
+ return { popup };
+};