Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
39 changes: 33 additions & 6 deletions ui/src/features/project/list/menu-actions.component.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
// Copyright (C) 2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

import { ActionButton, Item, Menu, MenuTrigger } from '@geti/ui';
import { ActionButton, Item, Key, Menu, MenuTrigger, toast } from '@geti/ui';
import { MoreMenu } from '@geti/ui/icons';

export const MenuActions = () => {
import { $api } from '../../../api/client';

export const MenuActions = ({ projectId }: { projectId: string }) => {
const deleteMutation = $api.useMutation('delete', '/api/projects/{project_id}', {
onSuccess: () => {
toast({ type: 'success', message: 'Project deleted successfully' });
},
onError: () => {
toast({ type: 'error', message: 'Failed to delete project' });
},
});

const handleMenuAction = (key: Key) => {
switch (key) {
case 'export':
// Handle export action
break;
case 'duplicate':
// Handle duplicate action
break;
case 'delete':
deleteMutation.mutate({ params: { path: { project_id: projectId } } });
break;
default:
break;
}
};

return (
<MenuTrigger>
<ActionButton isQuiet UNSAFE_style={{ fill: 'var(--spectrum-gray-900)' }}>
<MoreMenu />
</ActionButton>
<Menu>
<Item>Export</Item>
<Item>Duplicate</Item>
<Item>Delete</Item>
<Menu onAction={handleMenuAction}>
<Item key={'export'}>Export</Item>
<Item key={'duplicate'}>Duplicate</Item>
<Item key={'delete'}>Delete</Item>
</Menu>
</MenuTrigger>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const NewProjectLink = () => {
return (
<Link to={paths.project.new.pattern} className={classes.link}>
<AddCircle />
<Text>Add another project</Text>
<Text>Add project</Text>
</Link>
);
};
4 changes: 2 additions & 2 deletions ui/src/features/project/list/project-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type ProjectCardProps = {

export const ProjectCard = ({ item, isActive }: ProjectCardProps) => {
return (
// TODO: remove this empty string check once\
// TODO: remove this empty string check once
// https://github.com/open-edge-platform/training_extensions/issues/4721 is done
<NavLink to={paths.project.inference({ projectId: item.id || '' })}>
<Flex UNSAFE_className={clsx({ [classes.card]: true, [classes.activeCard]: isActive })}>
Expand All @@ -30,7 +30,7 @@ export const ProjectCard = ({ item, isActive }: ProjectCardProps) => {
<View width={'100%'} padding={'size-200'}>
<Flex alignItems={'center'} justifyContent={'space-between'}>
<Heading level={3}>{item.name}</Heading>
<MenuActions />
<MenuActions projectId={item.id || ''} />
</Flex>

<Flex marginBottom={'size-200'} gap={'size-50'}>
Expand Down
11 changes: 8 additions & 3 deletions ui/src/features/project/list/project-list.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { isEmpty } from 'lodash-es';

import { $api } from '../../../api/client';
import Background from '../../../assets/background.png';
import { mockedProjects } from './mocked-projects';
import { NewProjectLink } from './new-project-link.component';
import { ProjectCard } from './project-card';

Expand All @@ -27,7 +26,13 @@ export const ProjectList = () => {
backgroundSize: 'cover',
}}
>
<Content maxHeight={'90vh'} maxWidth={'1052px'} margin={'0 auto'} UNSAFE_style={{ overflow: 'auto' }}>
<Content
height={'100%'}
maxHeight={'90vh'}
maxWidth={'1052px'}
margin={'0 auto'}
UNSAFE_style={{ overflow: 'auto' }}
>
<Heading
level={1}
marginBottom={'size-250'}
Expand All @@ -49,7 +54,7 @@ export const ProjectList = () => {
gap={'size-300'}
marginX={'auto'}
justifyContent={'center'}
columns={isEmpty(mockedProjects) ? ['size-3600'] : ['1fr', '1fr']}
columns={isEmpty(projects.data) ? ['size-3600'] : ['1fr', '1fr']}
>
<NewProjectLink />

Expand Down
22 changes: 10 additions & 12 deletions ui/src/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { Flex, Grid, Item, TabList, TabPanels, Tabs, View } from '@geti/ui';
import { Outlet, useLocation } from 'react-router';
import { Link } from 'react-router-dom';

import { ReactComponent as BuildIcon } from './assets/icons/build-icon.svg';
import { ReactComponent as LiveFeedIcon } from './assets/icons/live-feed-icon.svg';
Expand All @@ -22,7 +23,7 @@ const Header = () => {
<View backgroundColor={'gray-300'} gridArea={'header'}>
<Flex height='100%' alignItems={'center'} marginX='1rem' gap='size-200'>
<View marginEnd='size-200'>
<span>Geti Tune</span>
<Link to={paths.project.index({})}>Geti Tune</Link>
</View>

<TabList
Expand All @@ -34,7 +35,7 @@ const Header = () => {
>
<Item
textValue='Inference page showing live inference on your project'
key={paths.project.inference({ projectId })}
key={'inference'}
href={paths.project.inference({ projectId })}
>
<Flex alignItems='center' gap='size-100'>
Expand All @@ -44,7 +45,7 @@ const Header = () => {
</Item>
<Item
textValue='Data collection page to visualise your media items'
key={paths.project.dataset({ projectId })}
key={'dataset'}
href={paths.project.dataset({ projectId })}
>
<Flex alignItems='center' gap='size-100'>
Expand All @@ -54,7 +55,7 @@ const Header = () => {
</Item>
<Item
textValue='Models page to visualise your models'
key={paths.project.models({ projectId })}
key={'models'}
href={paths.project.models({ projectId })}
>
<Flex alignItems='center' gap='size-100'>
Expand All @@ -69,14 +70,11 @@ const Header = () => {
};

const getFirstPathSegment = (path: string): string => {
const segments = path.split('/');

return segments.length > 1 ? `/${segments[1]}` : '/';
return path.split('/').pop() || '';
};

export const Layout = () => {
const { pathname } = useLocation();
const projectId = useProjectIdentifier();

return (
<Tabs aria-label='Header navigation' selectedKey={getFirstPathSegment(pathname)}>
Expand All @@ -92,16 +90,16 @@ export const Layout = () => {
<Header />
<View backgroundColor={'gray-50'} gridArea={'content'}>
<TabPanels height={'100%'} UNSAFE_style={{ border: 'none' }}>
<Item textValue='index' key={paths.project.index({})}>
<Item textValue='index' key={'index'}>
<Outlet />
</Item>
<Item textValue='inference' key={paths.project.inference({ projectId })}>
<Item textValue='inference' key={'inference'}>
<Outlet />
</Item>
<Item textValue='dataset' key={paths.project.dataset({ projectId })}>
<Item textValue='dataset' key={'dataset'}>
<Outlet />
</Item>
<Item textValue='models' key={paths.project.models({ projectId })}>
<Item textValue='models' key={'models'}>
<Outlet />
</Item>
</TabPanels>
Expand Down
Loading