feat: add main skill struct

This commit is contained in:
Joel
2026-01-14 16:27:54 +08:00
parent 1a8fd08563
commit ab531d946e
14 changed files with 232 additions and 33 deletions

View File

@ -0,0 +1,17 @@
import type { FC, PropsWithChildren } from 'react'
import * as React from 'react'
type EditorAreaProps = PropsWithChildren
const EditorArea: FC<EditorAreaProps> = ({ children }) => {
return (
<section
className="flex flex-1 flex-col gap-3 rounded-lg bg-white p-3"
data-component="editor-area"
>
{children}
</section>
)
}
export default React.memo(EditorArea)

View File

@ -0,0 +1,17 @@
import type { FC, PropsWithChildren } from 'react'
import * as React from 'react'
type EditorBodyProps = PropsWithChildren
const EditorBody: FC<EditorBodyProps> = ({ children }) => {
return (
<div
className="flex flex-1 rounded-md bg-gray-50 p-3"
data-component="editor-body"
>
{children}
</div>
)
}
export default React.memo(EditorBody)

View File

@ -0,0 +1,13 @@
import type { FC } from 'react'
import * as React from 'react'
const EditorTabItem: FC = () => {
return (
<div
className="h-7 w-24 rounded bg-gray-100"
data-component="editor-tab-item"
/>
)
}
export default React.memo(EditorTabItem)

View File

@ -0,0 +1,17 @@
import type { FC, PropsWithChildren } from 'react'
import * as React from 'react'
type EditorTabsProps = PropsWithChildren
const EditorTabs: FC<EditorTabsProps> = ({ children }) => {
return (
<div
className="flex items-center gap-2"
data-component="editor-tabs"
>
{children}
</div>
)
}
export default React.memo(EditorTabs)

View File

@ -0,0 +1,13 @@
import type { FC } from 'react'
import * as React from 'react'
const FileItem: FC = () => {
return (
<div
className="h-6 rounded bg-gray-100"
data-component="file-item"
/>
)
}
export default React.memo(FileItem)

View File

@ -0,0 +1,17 @@
import type { FC, PropsWithChildren } from 'react'
import * as React from 'react'
type FilesProps = PropsWithChildren
const Files: FC<FilesProps> = ({ children }) => {
return (
<div
className="flex flex-1 flex-col gap-2 overflow-auto"
data-component="files"
>
{children}
</div>
)
}
export default React.memo(Files)

View File

@ -0,0 +1,13 @@
import type { FC } from 'react'
import * as React from 'react'
const FoldItem: FC = () => {
return (
<div
className="h-6 rounded bg-gray-100"
data-component="fold-item"
/>
)
}
export default React.memo(FoldItem)

View File

@ -1,11 +1,40 @@
'use client'
import type { FC } from 'react'
import * as React from 'react'
import EditorArea from './editor-area'
import EditorBody from './editor-body'
import EditorTabItem from './editor-tab-item'
import EditorTabs from './editor-tabs'
import FileItem from './file-item'
import Files from './files'
import FoldItem from './fold-item'
import Sidebar from './sidebar'
import SidebarSearchAdd from './sidebar-search-add'
import SkillDocEditor from './skill-doc-editor'
import SkillPageLayout from './skill-page-layout'
const SkillMain: FC = () => {
return (
<div className="h-full bg-workflow-canvas-workflow-top-bar-1 pl-3 pt-[52px]">
Main
<SkillPageLayout>
<Sidebar>
<SidebarSearchAdd />
<Files>
<FoldItem />
<FileItem />
<FileItem />
</Files>
</Sidebar>
<EditorArea>
<EditorTabs>
<EditorTabItem />
<EditorTabItem />
</EditorTabs>
<EditorBody>
<SkillDocEditor />
</EditorBody>
</EditorArea>
</SkillPageLayout>
</div>
)
}

View File

@ -1,30 +1,30 @@
import type { SkillItem } from './type'
import { SKILL_ROOT_ID, SkillItemKind } from './type'
import type { ResourceItem } from './type'
import { ResourceKind, SKILL_ROOT_ID } from './type'
export const mockSkillItems: SkillItem[] = [
export const mockSkillItems: ResourceItem[] = [
{
id: 'skills',
name: 'skills',
parent_id: SKILL_ROOT_ID,
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'skills/_schemas',
name: '_schemas',
parent_id: 'skills',
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'skills/_schemas/email-writer',
name: 'email-writer',
parent_id: 'skills/_schemas',
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'skills/_schemas/email-writer/skill',
name: 'SKILL.md',
parent_id: 'skills/_schemas/email-writer',
kind: SkillItemKind.file,
kind: ResourceKind.file,
ext: 'md',
size: 1820,
},
@ -32,7 +32,7 @@ export const mockSkillItems: SkillItem[] = [
id: 'skills/_schemas/email-writer/prompt',
name: 'prompt.md',
parent_id: 'skills/_schemas/email-writer',
kind: SkillItemKind.file,
kind: ResourceKind.file,
ext: 'md',
size: 964,
},
@ -40,7 +40,7 @@ export const mockSkillItems: SkillItem[] = [
id: 'skills/_schemas/email-writer/output-schema',
name: 'output.schema.json',
parent_id: 'skills/_schemas/email-writer',
kind: SkillItemKind.file,
kind: ResourceKind.file,
ext: 'json',
size: 742,
},
@ -48,7 +48,7 @@ export const mockSkillItems: SkillItem[] = [
id: 'skills/_schemas/email-writer/toolmap',
name: 'toolmap.yaml',
parent_id: 'skills/_schemas/email-writer',
kind: SkillItemKind.file,
kind: ResourceKind.file,
ext: 'yaml',
size: 540,
},
@ -56,7 +56,7 @@ export const mockSkillItems: SkillItem[] = [
id: 'skills/_schemas/email-writer/examples',
name: 'examples.jsonl',
parent_id: 'skills/_schemas/email-writer',
kind: SkillItemKind.file,
kind: ResourceKind.file,
ext: 'jsonl',
size: 1205,
},
@ -64,7 +64,7 @@ export const mockSkillItems: SkillItem[] = [
id: 'skills/_index',
name: '_index.json',
parent_id: 'skills',
kind: SkillItemKind.file,
kind: ResourceKind.file,
ext: 'json',
size: 356,
},
@ -72,7 +72,7 @@ export const mockSkillItems: SkillItem[] = [
id: 'skills/_tags',
name: '_tags.json',
parent_id: 'skills',
kind: SkillItemKind.file,
kind: ResourceKind.file,
ext: 'json',
size: 212,
},
@ -80,42 +80,42 @@ export const mockSkillItems: SkillItem[] = [
id: 'skills/web-research',
name: 'web-research',
parent_id: 'skills',
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'skills/support-triage',
name: 'support-triage',
parent_id: 'skills',
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'knowledge',
name: 'knowledge',
parent_id: SKILL_ROOT_ID,
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'tools',
name: 'tools',
parent_id: SKILL_ROOT_ID,
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'templates',
name: 'templates',
parent_id: SKILL_ROOT_ID,
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'evals',
name: 'evals',
parent_id: SKILL_ROOT_ID,
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
{
id: 'dist',
name: 'dist',
parent_id: SKILL_ROOT_ID,
kind: SkillItemKind.folder,
kind: ResourceKind.folder,
},
]

View File

@ -0,0 +1,16 @@
import type { FC } from 'react'
import * as React from 'react'
const SidebarSearchAdd: FC = () => {
return (
<div
className="flex items-center gap-2"
data-component="sidebar-search-add"
>
<div className="h-8 flex-1 rounded-md bg-gray-100" />
<div className="h-8 w-8 rounded-md bg-gray-100" />
</div>
)
}
export default React.memo(SidebarSearchAdd)

View File

@ -0,0 +1,17 @@
import type { FC, PropsWithChildren } from 'react'
import * as React from 'react'
type SidebarProps = PropsWithChildren
const Sidebar: FC<SidebarProps> = ({ children }) => {
return (
<aside
className="flex w-[260px] shrink-0 flex-col gap-3 rounded-lg bg-white p-3"
data-component="sidebar"
>
{children}
</aside>
)
}
export default React.memo(Sidebar)

View File

@ -0,0 +1,13 @@
import type { FC } from 'react'
import * as React from 'react'
const SkillDocEditor: FC = () => {
return (
<div
className="h-full w-full rounded-md bg-white"
data-component="skill-doc-editor"
/>
)
}
export default React.memo(SkillDocEditor)

View File

@ -0,0 +1,17 @@
import type { FC, PropsWithChildren } from 'react'
import * as React from 'react'
type SkillPageLayoutProps = PropsWithChildren
const SkillPageLayout: FC<SkillPageLayoutProps> = ({ children }) => {
return (
<div
className="flex h-full gap-3"
data-component="skill-page-layout"
>
{children}
</div>
)
}
export default React.memo(SkillPageLayout)

View File

@ -1,29 +1,29 @@
export const SKILL_ROOT_ID = 'root' as const
export type SkillItemId = string
export type SkillParentId = SkillItemId | typeof SKILL_ROOT_ID | null
export type ItemId = string
export type ParentId = ItemId | typeof SKILL_ROOT_ID | null
export enum SkillItemKind {
export enum ResourceKind {
folder = 'folder',
file = 'file',
}
export type SkillItemBase = {
id: SkillItemId
export type ResourceItemBase = {
id: ItemId
name: string
parent_id: SkillParentId
parent_id: ParentId
path?: string
}
export type SkillFolderItem = SkillItemBase & {
kind: 'folder'
export type FolderItem = ResourceItemBase & {
kind: ResourceKind.folder
}
export type SkillFileItem = SkillItemBase & {
kind: 'file'
export type FileItem = ResourceItemBase & {
kind: ResourceKind.file
ext?: string
size?: number
}
export type SkillItem = SkillFolderItem | SkillFileItem
export type ResourceItem = FolderItem | FileItem
export type SkillList = SkillItem[]
export type ResourceItemList = ResourceItem[]