Feat: 워크스페이스 레이블 탐색 바 추가 - S11P21S002-76
This commit is contained in:
parent
53cb5b1388
commit
701fd873e8
46
frontend/src/components/WorkspaceLabelBar/LabelButton.tsx
Normal file
46
frontend/src/components/WorkspaceLabelBar/LabelButton.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { Label } from '@/types';
|
||||||
|
import { Edit, Trash2 } from 'lucide-react';
|
||||||
|
import { MouseEventHandler } from 'react';
|
||||||
|
|
||||||
|
export default function LabelButton({ id, name, color }: Label) {
|
||||||
|
const handleClick: MouseEventHandler = () => {
|
||||||
|
console.log(`LabelButton ${id} clicked`);
|
||||||
|
};
|
||||||
|
const handleEdit: MouseEventHandler = (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
console.log(`Edit LabelButton ${id}`);
|
||||||
|
};
|
||||||
|
const handleDelete: MouseEventHandler = (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
console.log(`Delete LabelButton ${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center gap-2.5 rounded-lg bg-gray-100 p-2.5 transition-colors hover:bg-gray-200">
|
||||||
|
<button
|
||||||
|
className="flex grow items-center gap-2.5 text-left"
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="h-3 w-3 rounded-full"
|
||||||
|
style={{
|
||||||
|
backgroundColor: color,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span className="body grow text-gray-900">{name}</span>
|
||||||
|
</button>
|
||||||
|
<button onClick={handleEdit}>
|
||||||
|
<Edit
|
||||||
|
size={16}
|
||||||
|
className="stroke-gray-500 hover:stroke-gray-600"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button onClick={handleDelete}>
|
||||||
|
<Trash2
|
||||||
|
size={16}
|
||||||
|
className="stroke-red-500 hover:stroke-red-600"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
35
frontend/src/components/WorkspaceLabelBar/index.stories.tsx
Normal file
35
frontend/src/components/WorkspaceLabelBar/index.stories.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { Meta } from '@storybook/react';
|
||||||
|
import WorkspaceLabelBar from '.';
|
||||||
|
import { Label } from '@/types';
|
||||||
|
|
||||||
|
const meta: Meta<typeof WorkspaceLabelBar> = {
|
||||||
|
title: 'Workspace/WorkspaceLabelBar',
|
||||||
|
component: WorkspaceLabelBar,
|
||||||
|
parameters: {
|
||||||
|
layout: 'fullscreen',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
const labels: Label[] = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Label 1',
|
||||||
|
color: '#FFaa33',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'Label 2',
|
||||||
|
color: '#aaFF55',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'Label 3',
|
||||||
|
color: '#77aaFF',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const Default = () => {
|
||||||
|
return <WorkspaceLabelBar labels={labels} />;
|
||||||
|
};
|
41
frontend/src/components/WorkspaceLabelBar/index.tsx
Normal file
41
frontend/src/components/WorkspaceLabelBar/index.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { Label } from '@/types';
|
||||||
|
import LabelButton from './LabelButton';
|
||||||
|
import { Button } from '../ui/button';
|
||||||
|
import { Play } from 'lucide-react';
|
||||||
|
|
||||||
|
export default function WorkspaceLabelBar({ labels }: { labels: Label[] }) {
|
||||||
|
const handleAutoLabeling = () => {
|
||||||
|
console.log('Auto labeling');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex h-full w-[280px] flex-col justify-between border-l border-gray-300 bg-gray-100">
|
||||||
|
<div className="flex flex-col gap-2.5">
|
||||||
|
<header className="subheading flex w-full items-center gap-2 px-5 py-2.5">
|
||||||
|
<h1 className="w-full overflow-hidden text-ellipsis whitespace-nowrap">레이블 목록</h1>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-col gap-1 px-2.5">
|
||||||
|
{labels.map((label) => (
|
||||||
|
<LabelButton
|
||||||
|
key={label.id}
|
||||||
|
{...label}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex p-2.5">
|
||||||
|
<Button
|
||||||
|
variant="outlinePrimary"
|
||||||
|
className="w-full"
|
||||||
|
onClick={handleAutoLabeling}
|
||||||
|
>
|
||||||
|
<Play
|
||||||
|
size={16}
|
||||||
|
className="mr-1"
|
||||||
|
/>
|
||||||
|
<span>자동 레이블링</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -19,3 +19,9 @@ export type Project = {
|
|||||||
type: 'Classification' | 'Detection' | 'Segmentation';
|
type: 'Classification' | 'Detection' | 'Segmentation';
|
||||||
children: Array<DirectoryItem | FileItem>;
|
children: Array<DirectoryItem | FileItem>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Label = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
color: string;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user