diff --git a/webui/src/app/index.tsx b/webui/src/app/index.tsx
index b3ab52c..2050ff8 100644
--- a/webui/src/app/index.tsx
+++ b/webui/src/app/index.tsx
@@ -1,75 +1,9 @@
-import { useQuery } from '@tanstack/react-query';
+import { Redirect } from 'expo-router';
-import type { EntryGraphData } from '~/app/api/stats/[entry]/modules/index+api';
-import { Page, PageHeader, PageTitle } from '~/components/Page';
-import { StatsModuleFilter } from '~/components/forms/StatsModuleFilter';
-import { TreemapGraph } from '~/components/graphs/TreemapGraph';
-import {
- type ModuleFilters,
- useModuleFilterContext,
- filtersToUrlParams,
-} from '~/providers/modules';
-import { useStatsEntryContext } from '~/providers/stats';
-import { Tag } from '~/ui/Tag';
-import { fetchApi } from '~/utils/api';
-import { formatFileSize } from '~/utils/formatString';
+import { useStatsEntry } from '~/providers/stats';
-export default function GraphScreen() {
- const { entryId } = useStatsEntryContext();
- const { filters } = useModuleFilterContext();
+export default function HomeScreen() {
+ const { entry } = useStatsEntry();
- const graph = useBundleGraphData(entryId, filters);
-
- return (
-
-
-
-
- Bundle
- {!!graph.data && }
-
-
-
-
-
-
- );
-}
-
-function BundleSummary({ data }: { data: EntryGraphData }) {
- return (
-
-
-
-
-
{data.metadata.modulesCount} modules
-
-
-
{formatFileSize(data.metadata.size)}
- {data.metadata.modulesCount !== data.data.modulesCount && (
-
- —
- visible:
- {data.data.modulesCount} modules
- -
- {formatFileSize(data.data.size)}
-
- )}
-
- );
-}
-
-/** Load the bundle graph data from API, with default or custom filters */
-function useBundleGraphData(entryId: string, filters?: ModuleFilters) {
- return useQuery({
- queryKey: [`bundle-graph`, entryId, filters],
- queryFn: ({ queryKey }) => {
- const [_key, entry, filters] = queryKey as [string, string, ModuleFilters | undefined];
- const url = filters
- ? `/api/stats/${entry}/modules?${filtersToUrlParams(filters)}`
- : `/api/stats/${entry}/modules`;
-
- return fetchApi(url)
- .then((res) => (res.ok ? res : Promise.reject(res)))
- .then((res) => res.json());
- },
- });
+ return ;
}
diff --git a/webui/src/app/folders/[path].tsx b/webui/src/app/stats/[entry]/folders/[path].tsx
similarity index 86%
rename from webui/src/app/folders/[path].tsx
rename to webui/src/app/stats/[entry]/folders/[path].tsx
index 332cded..4d57b56 100644
--- a/webui/src/app/folders/[path].tsx
+++ b/webui/src/app/stats/[entry]/folders/[path].tsx
@@ -1,21 +1,21 @@
import { useQuery } from '@tanstack/react-query';
import { useLocalSearchParams } from 'expo-router';
-import { type FolderGraphData } from '../api/stats/[entry]/folders/index+api';
-
+import { type FolderGraphData } from '~/app/api/stats/[entry]/folders/index+api';
import { Page, PageHeader, PageTitle } from '~/components/Page';
import { TreemapGraph } from '~/components/graphs/TreemapGraph';
-import { useStatsEntryContext } from '~/providers/stats';
+import { useStatsEntry } from '~/providers/stats';
import { Skeleton } from '~/ui/Skeleton';
import { Tag } from '~/ui/Tag';
import { fetchApi } from '~/utils/api';
import { formatFileSize } from '~/utils/formatString';
+import { relativeEntryPath } from '~/utils/stats';
import { type PartialStatsEntry } from '~core/data/types';
export default function FolderPage() {
- const { entryId, entry, entryFilePath } = useStatsEntryContext();
+ const { entry } = useStatsEntry();
const { path: absolutePath } = useLocalSearchParams<{ path: string }>();
- const folder = useFolderData(entryId, absolutePath!);
+ const folder = useFolderData(entry.id, absolutePath!);
if (folder.isLoading) {
return ;
@@ -39,15 +39,15 @@ export default function FolderPage() {
className="text-slate-50 font-bold text-lg mr-4"
title={folder.data.metadata.folderPath}
>
- {entryFilePath(folder.data.metadata.folderPath)}/
+ {relativeEntryPath(entry, folder.data.metadata.folderPath)}/
diff --git a/webui/src/app/stats/[entry]/index.tsx b/webui/src/app/stats/[entry]/index.tsx
new file mode 100644
index 0000000..c811128
--- /dev/null
+++ b/webui/src/app/stats/[entry]/index.tsx
@@ -0,0 +1,75 @@
+import { useQuery } from '@tanstack/react-query';
+
+import type { EntryGraphData } from '~/app/api/stats/[entry]/modules/index+api';
+import { Page, PageHeader, PageTitle } from '~/components/Page';
+import { StatsModuleFilter } from '~/components/forms/StatsModuleFilter';
+import { TreemapGraph } from '~/components/graphs/TreemapGraph';
+import {
+ type ModuleFilters,
+ useModuleFilterContext,
+ filtersToUrlParams,
+} from '~/providers/modules';
+import { useStatsEntry } from '~/providers/stats';
+import { Tag } from '~/ui/Tag';
+import { fetchApi } from '~/utils/api';
+import { formatFileSize } from '~/utils/formatString';
+
+export default function StatsScreen() {
+ const { entry } = useStatsEntry();
+ const { filters } = useModuleFilterContext();
+
+ const graph = useBundleGraphData(entry.id, filters);
+
+ return (
+
+
+
+
+ Bundle
+ {!!graph.data && }
+
+
+
+
+
+
+ );
+}
+
+function BundleSummary({ data }: { data: EntryGraphData }) {
+ return (
+
+
+
-
+
{data.metadata.modulesCount} modules
+
-
+
{formatFileSize(data.metadata.size)}
+ {data.metadata.modulesCount !== data.data.modulesCount && (
+
+ —
+ visible:
+ {data.data.modulesCount} modules
+ -
+ {formatFileSize(data.data.size)}
+
+ )}
+
+ );
+}
+
+/** Load the bundle graph data from API, with default or custom filters */
+function useBundleGraphData(entryId: string, filters?: ModuleFilters) {
+ return useQuery({
+ queryKey: [`bundle-graph`, entryId, filters],
+ queryFn: ({ queryKey }) => {
+ const [_key, entry, filters] = queryKey as [string, string, ModuleFilters | undefined];
+ const url = filters
+ ? `/api/stats/${entry}/modules?${filtersToUrlParams(filters)}`
+ : `/api/stats/${entry}/modules`;
+
+ return fetchApi(url)
+ .then((res) => (res.ok ? res : Promise.reject(res)))
+ .then((res) => res.json());
+ },
+ });
+}
diff --git a/webui/src/app/modules/[path].tsx b/webui/src/app/stats/[entry]/modules/[path].tsx
similarity index 89%
rename from webui/src/app/modules/[path].tsx
rename to webui/src/app/stats/[entry]/modules/[path].tsx
index 5e54d94..2755d6c 100644
--- a/webui/src/app/modules/[path].tsx
+++ b/webui/src/app/stats/[entry]/modules/[path].tsx
@@ -2,18 +2,19 @@ import { useQuery } from '@tanstack/react-query';
import { Link, useLocalSearchParams } from 'expo-router';
import { Page, PageHeader, PageTitle } from '~/components/Page';
-import { useStatsEntryContext } from '~/providers/stats';
+import { useStatsEntry } from '~/providers/stats';
import { CodeBlock, CodeBlockSectionWithPrettier, guessLanguageFromPath } from '~/ui/CodeBlock';
import { Skeleton } from '~/ui/Skeleton';
import { Tag } from '~/ui/Tag';
import { fetchApi } from '~/utils/api';
import { formatFileSize } from '~/utils/formatString';
+import { relativeEntryPath } from '~/utils/stats';
import { type PartialStatsEntry, type StatsModule } from '~core/data/types';
export default function ModulePage() {
- const { entryId, entry, entryFilePath } = useStatsEntryContext();
+ const { entry } = useStatsEntry();
const { path: absolutePath } = useLocalSearchParams<{ path: string }>();
- const module = useModuleData(entryId, absolutePath!);
+ const module = useModuleData(entry.id, absolutePath!);
const outputCode = module.data?.output?.map((output) => output.data.code).join('\n');
@@ -35,7 +36,7 @@ export default function ModulePage() {
- {entryFilePath(module.data.path)}
+ {relativeEntryPath(entry, module.data.path)}
@@ -50,9 +51,12 @@ export default function ModulePage() {
- {entryFilePath(path)}
+ {relativeEntryPath(entry, path)}
))}
diff --git a/webui/src/components/forms/StatsEntrySelect.tsx b/webui/src/components/forms/StatsEntrySelect.tsx
index 01fb94a..09c3327 100644
--- a/webui/src/components/forms/StatsEntrySelect.tsx
+++ b/webui/src/components/forms/StatsEntrySelect.tsx
@@ -1,26 +1,25 @@
import * as Select from '@radix-ui/react-select';
import cn from 'classnames';
+import { useRouter } from 'expo-router';
// @ts-expect-error
import ChevronDownIcon from 'lucide-react/dist/esm/icons/chevron-down';
// @ts-expect-error
import ChevronUpIcon from 'lucide-react/dist/esm/icons/chevron-up';
-import { useStatsEntryContext } from '~/providers/stats';
+import { useStatsEntry } from '~/providers/stats';
import { Button } from '~/ui/Button';
import { Tag } from '~/ui/Tag';
+import { relativeEntryPath } from '~/utils/stats';
export function StatsEntrySelect() {
- const { entryId, setEntryId, entry, entries } = useStatsEntryContext();
-
- function onEntryChange(value: string) {
- setEntryId(value);
- }
+ const router = useRouter();
+ const { entry, entries } = useStatsEntry();
return (
-
+ router.setParams({ entry })}>