diff --git a/studio/src/components/dashboard/graph-command-group.tsx b/studio/src/components/dashboard/graph-command-group.tsx
index e4fb695db1..f9c80215ef 100644
--- a/studio/src/components/dashboard/graph-command-group.tsx
+++ b/studio/src/components/dashboard/graph-command-group.tsx
@@ -67,6 +67,15 @@ interface GraphLinkProps {
setNamespace(namespace: string): void;
}
+const defaultGraphTemplate = `/[organizationSlug]/[namespace]/graph/[slug]`;
+const graphAreasWithParameters: readonly string[] = [
+ 'change-log',
+ 'checks',
+ 'compositions',
+ 'feature-flags',
+ 'proposals'
+];
+
function GraphCommandItem({
name,
namespace,
@@ -82,16 +91,22 @@ function GraphCommandItem({
const pathname = useMemo(
() => {
- const segment = router.pathname.split('/')[3]?.toLowerCase();
+ const segmentSplit = router.pathname.split('/');
+ const segment = segmentSplit[3]?.toLowerCase();
if (isSubgraph) {
return segment === 'subgraph'
? router.pathname
: `/[organizationSlug]/[namespace]/subgraph/[subgraphSlug]`;
}
- return segment === 'graph'
- ? router.pathname
- : `/[organizationSlug]/[namespace]/graph/[slug]`;
+ if (segment !== 'graph') {
+ return defaultGraphTemplate;
+ }
+
+ const areaSegment = segmentSplit[5]?.toLowerCase();
+ return areaSegment && graphAreasWithParameters.includes(areaSegment) && segmentSplit.length > 5
+ ? `${defaultGraphTemplate}/${areaSegment}`
+ : router.pathname;
},
[router.pathname, isSubgraph],
);
diff --git a/studio/src/components/dashboard/namespace-selector.tsx b/studio/src/components/dashboard/namespace-selector.tsx
index c3cd42f794..b75149d1f1 100644
--- a/studio/src/components/dashboard/namespace-selector.tsx
+++ b/studio/src/components/dashboard/namespace-selector.tsx
@@ -6,8 +6,7 @@ import { useMemo, useState } from "react";
import Link from "next/link";
import { cn } from "@/lib/utils";
import * as React from "react";
-import { CheckIcon } from "@radix-ui/react-icons";
-import { CaretSortIcon } from "@radix-ui/react-icons";
+import { CheckIcon, CaretSortIcon } from "@radix-ui/react-icons";
import { docsBaseURL } from "@/lib/constants";
import { WorkspaceCommandWrapper } from "./workspace-command-wrapper"
import { useCurrentOrganization } from "@/hooks/use-current-organization";
@@ -20,7 +19,7 @@ interface NamespaceSelectorProps {
export function NamespaceSelector({ isViewingGraphOrSubgraph, truncateNamespace }: NamespaceSelectorProps) {
const [filter, setFilter] = useState('');
const [isOpen, setOpen] = useState(false);
- const { namespace, namespaceByName, setNamespace } = useWorkspace();
+ const { isLoading, namespace, namespaceByName, setNamespace } = useWorkspace();
const router = useRouter();
const organizationSlug = useCurrentOrganization()?.slug;
@@ -30,6 +29,22 @@ export function NamespaceSelector({ isViewingGraphOrSubgraph, truncateNamespace
);
const namespaces = Array.from(namespaceByName.keys());
+ if (isLoading) {
+ return (
+
+
+ {namespace.name}
+
+
+
+ );
+ }
return (
@@ -48,7 +63,6 @@ export function NamespaceSelector({ isViewingGraphOrSubgraph, truncateNamespace
{namespace.name}
)}
-
([], { keys: ['name'], threshold: 0.3, });
+ const fuse = new Fuse([], { keys: ['name'], threshold: 0.2, includeScore: true });
const searchResults: WorkspaceNamespace[] = [];
for (const wns of Array.from(namespaceByName.values())) {
- if (!wns.graphs?.length) {
- // The namespace doesn't contain any federated graph, we don't need to perform the search here
- continue;
- }
-
// Determine whether the namespace contains the filter value
- fuse.setCollection([wns]);
- if (fuse.search(filterValue).length > 0) {
+ if (wns.name.toLowerCase().includes(filterValue)) {
// The namespace contains the filter value, add it with all the graphs/subgraphs to the search results
searchResults.push(wns);
continue;
}
+ if (!wns.graphs?.length) {
+ // The namespace doesn't contain any federated graph, we don't need to perform the search here
+ continue;
+ }
+
// We need to clone the namespace to avoid mutating the original object
const clonedWns = wns.clone();
clonedWns.graphs = [];
diff --git a/studio/src/components/dashboard/workspace-provider.tsx b/studio/src/components/dashboard/workspace-provider.tsx
index ef7c6fc0ca..63d85937d5 100644
--- a/studio/src/components/dashboard/workspace-provider.tsx
+++ b/studio/src/components/dashboard/workspace-provider.tsx
@@ -59,12 +59,14 @@ export function WorkspaceProvider({ children }: React.PropsWithChildren) {
// Memoize context components
const currentNamespace= useMemo(
- () => data?.namespaces.find((wns) => wns.name === namespace) ?? new WorkspaceNamespace({
- id: '',
- name: DEFAULT_NAMESPACE_NAME,
- graphs: [],
- }),
- [data?.namespaces, namespace],
+ () => isLoading
+ ? new WorkspaceNamespace({ id: '', name: namespace, graphs: [] })
+ : data?.namespaces.find((wns) => wns.name === namespace) ?? new WorkspaceNamespace({
+ id: '',
+ name: DEFAULT_NAMESPACE_NAME,
+ graphs: [],
+ }),
+ [isLoading, data?.namespaces, namespace],
);
const namespaceByName = useMemo(
diff --git a/studio/src/components/dashboard/workspace-selector.tsx b/studio/src/components/dashboard/workspace-selector.tsx
index 59ccd46e30..a381231a58 100644
--- a/studio/src/components/dashboard/workspace-selector.tsx
+++ b/studio/src/components/dashboard/workspace-selector.tsx
@@ -39,7 +39,7 @@ export function WorkspaceSelector({ children, truncateNamespace = true }: Worksp
const isViewingGraphOrSubgraph = !!activeGraph || !!activeSubgraph;
return (
-
+
{breadcrumbs?.map((b, i) => (
diff --git a/studio/src/pages/[organizationSlug]/feature-flags/[featureFlagSlug]/index.tsx b/studio/src/pages/[organizationSlug]/feature-flags/[featureFlagSlug]/index.tsx
index f7fc794ad1..04c0534662 100644
--- a/studio/src/pages/[organizationSlug]/feature-flags/[featureFlagSlug]/index.tsx
+++ b/studio/src/pages/[organizationSlug]/feature-flags/[featureFlagSlug]/index.tsx
@@ -11,6 +11,7 @@ import { Button } from "@/components/ui/button";
import Link from "next/link";
import { FeatureFlagDetails } from "@/components/feature-flag-details";
import { useWorkspace } from "@/hooks/use-workspace";
+import { NamespaceSelector } from "@/components/dashboard/namespace-selector";
import { useCurrentOrganization } from "@/hooks/use-current-organization";
const FeatureFlagDetailsPage: NextPageWithLayout = () => {
@@ -89,8 +90,13 @@ FeatureFlagDetailsPage.getLayout = (page) => {
undefined,
undefined,
[
- ,
- ,
+ ,
+ ,
+ ,
],
true,
);