Skip to content

move everything to joins page, update search/default page, etc #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions frontend/src/lib/components/NavigationBar/NavigationBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
AdjustmentsHorizontal,
ArrowsUpDown
} from 'svelte-hero-icons';
import type { IconSource } from 'svelte-hero-icons';
import { goto } from '$app/navigation';
import { isMacOS } from '$lib/util/browser';
import { Badge } from '$lib/components/ui/badge';
import { getEntity, type Entity } from '$lib/types/Entity/Entity';

type Props = {
navItems: { label: string; href: string; icon: IconSource }[];
navItems: Entity[];
user: { name: string; avatar: string };
};

Expand Down Expand Up @@ -130,16 +130,16 @@
{#each navItems as item}
<li>
<Button
variant={isActiveRoute(item.href) ? 'default' : 'ghost'}
variant={isActiveRoute(item.path) ? 'default' : 'ghost'}
size="nav"
href={item.href}
href={item.path}
icon="leading"
>
<Icon
src={item.icon}
micro
size="16"
class={isActiveRoute(item.href) ? 'text-muted-icon-primary' : 'text-muted-icon-neutral'}
class={isActiveRoute(item.path) ? 'text-muted-icon-primary' : 'text-muted-icon-neutral'}
/>
{item.label}
</Button>
Expand Down Expand Up @@ -202,9 +202,31 @@
{:else}
<CommandGroup heading={`Search for "${input}"`}>
{#each searchResults as model}
<CommandItem onSelect={() => handleSelect(`/models/${encodeURIComponent(model.name)}`)}>
<CommandItem
disabled
onSelect={() =>
handleSelect(`${getEntity('models').path}/${encodeURIComponent(model.name)}`)}
>
<Icon src={getEntity('models').icon} micro size="16" />
{model.name}
</CommandItem>
<CommandItem
onSelect={() =>
handleSelect(`${getEntity('joins').path}/${encodeURIComponent(model.join.name)}`)}
>
<Icon src={getEntity('joins').icon} micro size="16" />
{model.join.name}
</CommandItem>
{#each model.join.groupBys as groupBy}
<CommandItem
disabled
onSelect={() =>
handleSelect(`${getEntity('groupbys').path}/${encodeURIComponent(groupBy.name)}`)}
>
<Icon src={getEntity('groupbys').icon} micro size="16" />
{groupBy.name}
</CommandItem>
{/each}
Comment on lines +205 to +229
Copy link

@coderabbitai coderabbitai bot Nov 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Based on the search results, I can now generate a final response:

Backend search endpoint needs to be updated for new entity types

The current search implementation in SearchController.scala only supports searching model names, but the frontend is now displaying joins and groupBys in search results. The backend needs to be extended to support these entity types.

  • hub/app/controllers/SearchController.scala: Comment explicitly states "currently we only support searching model names"
  • frontend/src/lib/api/api.ts: Frontend search function returns ModelsResponse type, suggesting backend only returns models
🔗 Analysis chain

Verify search implementation for new entity types

The search results now include joins and groupBys. Let's verify that the backend search endpoint properly handles these new entity types.

Run the following script to check the search implementation:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify search endpoint implementation for new entity types

# Check the search endpoint implementation
rg -A 10 "search.*function|search.*endpoint" --type typescript

# Check for join/groupBy handling in search-related code
rg -A 5 "join.*search|groupBy.*search" --type typescript

Length of output: 193


Script:

#!/bin/bash
# Let's try without typescript file type and use more specific patterns

# Check search-related implementations
rg -A 10 'search.*function|search.*endpoint|function.*search'

# Check for join/groupBy handling in search-related code
rg -A 5 'join.*search|groupBy.*search|search.*join|search.*groupBy'

# Look for API routes or handlers related to search
fd -e ts -e js "search" --exec cat {}

Length of output: 5185

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@piyush-zlai This is relevant - search only works for at the model level. i.e. a search of "foo" will not match a model named "bar" with a join named "foo"

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

{/each}
</CommandGroup>
{/if}
Expand Down
32 changes: 32 additions & 0 deletions frontend/src/lib/types/Entity/Entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Cube, PuzzlePiece, Square3Stack3d } from 'svelte-hero-icons';

export const entityConfig = [
{
label: 'Models',
path: '/models',
icon: Cube,
id: 'models'
},
{
label: 'GroupBys',
path: '/groupbys',
icon: PuzzlePiece,
id: 'groupbys'
},
{
label: 'Joins',
path: '/joins',
icon: Square3Stack3d,
id: 'joins'
}
] as const;

export type Entity = (typeof entityConfig)[number];
export type EntityId = Entity['id'];

// Helper function to get entity by ID
export function getEntity(id: EntityId): Entity {
const entity = entityConfig.find((entity) => entity.id === id);
if (!entity) throw new Error(`Entity with id "${id}" not found`);
return entity;
}
4 changes: 2 additions & 2 deletions frontend/src/lib/types/Model/Model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('Model types', () => {

if (timeseriesResult.items.length > 0) {
const item = timeseriesResult.items[0];
const expectedItemKeys = ['value', 'ts', 'label'];
const expectedItemKeys = ['value', 'ts', 'label', 'nullValue'];
expect(Object.keys(item)).toEqual(expect.arrayContaining(expectedItemKeys));

// Log a warning if there are additional fields
Expand Down Expand Up @@ -184,7 +184,7 @@ describe('Model types', () => {

if (subItem.points.length > 0) {
const point = subItem.points[0];
const expectedPointKeys = ['value', 'ts', 'label'];
const expectedPointKeys = ['value', 'ts', 'label', 'nullValue'];
expect(Object.keys(point)).toEqual(expect.arrayContaining(expectedPointKeys));

// Log a warning if there are additional fields
Expand Down
12 changes: 11 additions & 1 deletion frontend/src/lib/types/Model/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export type Model = {
production: boolean;
team: string;
modelType: string;
join: JoinTimeSeriesResponse; // todo: this type needs to be updated to match the actual response once that WIP is finished
join: Join;
};

export type ModelsResponse = {
Expand All @@ -23,6 +23,16 @@ export type TimeSeriesResponse = {
id: string;
items: TimeSeriesItem[];
};
export type Join = {
name: string;
joinFeatures: string[];
groupBys: GroupBy[];
};

export type GroupBy = {
name: string;
features: string[];
};

export type JoinTimeSeriesResponse = {
name: string; // todo: rename to joinName
Expand Down
10 changes: 2 additions & 8 deletions frontend/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import NavigationBar from '$lib/components/NavigationBar/NavigationBar.svelte';
import BreadcrumbNav from '$lib/components/BreadcrumbNav/BreadcrumbNav.svelte';
import { ScrollArea } from '$lib/components/ui/scroll-area';
import { Cube, PuzzlePiece, Square3Stack3d } from 'svelte-hero-icons';
import { entityConfig } from '$lib/types/Entity/Entity';
let { children }: { children: Snippet } = $props();
Expand All @@ -16,20 +16,14 @@
avatar: '/path/to/avatar.jpg'
};
const navItems = [
{ label: 'Models', href: '/models', icon: Cube },
{ label: 'GroupBys', href: '/groupbys', icon: PuzzlePiece },
{ label: 'Joins', href: '/joins', icon: Square3Stack3d }
];
const breadcrumbs = $derived($page.url.pathname.split('/').filter(Boolean));
</script>

<div class="flex h-screen">
<NavigationSlider />

<!-- Left navigation -->
<NavigationBar {navItems} {user} />
<NavigationBar navItems={entityConfig.filter((entity) => entity.id === 'joins')} {user} />

<!-- Main content -->
<main
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { redirect } from '@sveltejs/kit';

export function load({ url }) {
if (url.pathname === '/') {
throw redirect(307, '/models');
throw redirect(307, '/joins');
}
}
5 changes: 0 additions & 5 deletions frontend/src/routes/groupbys/+page.svelte

This file was deleted.

61 changes: 58 additions & 3 deletions frontend/src/routes/joins/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
<script>
import ComingSoonPage from '$lib/components/ComingSoonPage/ComingSoonPage.svelte';
<script lang="ts">
import type { Model } from '$lib/types/Model/Model';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from '$lib/components/ui/table';
import TrueFalseBadge from '$lib/components/TrueFalseBadge/TrueFalseBadge.svelte';
import Separator from '$lib/components/ui/separator/separator.svelte';
import PageHeader from '$lib/components/PageHeader/PageHeader.svelte';
import ActionButtons from '$lib/components/ActionButtons/ActionButtons.svelte';

const { data } = $props();
const models: Model[] = $state(data.models.items);
</script>

<ComingSoonPage />
<PageHeader title="Joins"></PageHeader>

<div class="w-full">
<ActionButtons class="mb-4" />
</div>
<Separator fullWidthExtend={true} />
<Table>
<TableHeader>
<TableRow>
<TableHead>Join</TableHead>
<TableHead>Model</TableHead>
<TableHead>Team</TableHead>
<TableHead>Type</TableHead>
<TableHead>Online</TableHead>
<TableHead>Production</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{#each models as model}
<TableRow>
<TableCell>
<a href={'/joins/' + encodeURIComponent(model.join.name)} class="hover:underline">
{model.join.name}
</a>
</TableCell>
<TableCell>
{model.name}
</TableCell>
<TableCell>{model.team}</TableCell>
<TableCell>{model.modelType}</TableCell>
<TableCell>
<TrueFalseBadge isTrue={model.online} />
</TableCell>
<TableCell>
<TrueFalseBadge isTrue={model.production} />
</TableCell>
</TableRow>
{/each}
</TableBody>
</Table>
<Separator fullWidthExtend={true} />
56 changes: 0 additions & 56 deletions frontend/src/routes/models/+page.svelte

This file was deleted.