Skip to content

Commit

Permalink
prepare the ground for Workflow integration
Browse files Browse the repository at this point in the history
  • Loading branch information
jbilcke-hf committed Jul 24, 2024
1 parent df1a98f commit a54bba5
Show file tree
Hide file tree
Showing 33 changed files with 637 additions and 1,276 deletions.
1,360 changes: 210 additions & 1,150 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"dependencies": {
"@aitube/broadway": "0.1.2",
"@aitube/clap": "0.1.2",
"@aitube/clapper-services": "0.1.2",
"@aitube/clapper-services": "0.1.2-0",
"@aitube/engine": "0.1.2",
"@aitube/timeline": "0.1.2",
"@fal-ai/serverless-client": "^0.13.0",
Expand Down
3 changes: 3 additions & 0 deletions src/components/editors/Editors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useTheme } from '@/services/ui/useTheme'
import { EntityEditor } from './EntityEditor'
import { ProjectEditor } from './ProjectEditor'
import { SegmentEditor } from './SegmentEditor'
import { WorkflowEditor } from './WorkflowEditor'

export function Editors() {
const theme = useTheme()
Expand All @@ -31,6 +32,8 @@ export function Editors() {
<EntityEditor />
) : view === EditorView.SEGMENT ? (
<SegmentEditor />
) : view === EditorView.WORKFLOW ? (
<WorkflowEditor />
) : (
<div>TODO</div>
)}
Expand Down
6 changes: 5 additions & 1 deletion src/components/editors/ProjectEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ export function ProjectEditor() {
}, [clap?.meta, setCurrent])

if (!current) {
return <div>Loading..</div>
return (
<FormSection label={'Project Settings'} className="p-4">
Loading project..
</FormSection>
)
}

// TODO: adapt the editor based on the kind of
Expand Down
6 changes: 5 additions & 1 deletion src/components/editors/SegmentEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ export function SegmentEditor() {
}, [setCurrent, selectedSegments.map((s) => s.id).join(',')])

if (!current) {
return <div>No segment selected</div>
return (
<FormSection label={'Segment Editor'} className="p-4">
No segment selected.
</FormSection>
)
}

return (
Expand Down
30 changes: 30 additions & 0 deletions src/components/editors/WorkflowEditor/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useEffect } from 'react'

import { FormInput } from '@/components/forms/FormInput'
import { FormSection } from '@/components/forms/FormSection'
import { useWorkflowEditor } from '@/services/editors'

export function WorkflowEditor() {
const current = useWorkflowEditor((s) => s.current)
const setCurrent = useWorkflowEditor((s) => s.setCurrent)
const history = useWorkflowEditor((s) => s.history)
const undo = useWorkflowEditor((s) => s.undo)
const redo = useWorkflowEditor((s) => s.redo)

if (!current) {
return (
<FormSection label={'Workflow Editor'} className="p-4">
Workflows are not implemented yet.
</FormSection>
)
}

return (
<FormSection label={'Workflow Editor'} className="p-4">
<div>Should be a form to edit the parameters.</div>
<div>
We can also display a link or an iframe with the actual workflow graph.
</div>
</FormSection>
)
}
13 changes: 4 additions & 9 deletions src/components/toolbars/editors-menu/EditorsSideMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
MdOutlineHistoryEdu,
} from 'react-icons/md'
import { LuClapperboard } from 'react-icons/lu'
import { PiTreeStructureBold } from 'react-icons/pi'
import { IoFilmOutline } from 'react-icons/io5'
import { EditorView } from '@aitube/clapper-services'

Expand Down Expand Up @@ -39,15 +40,9 @@ export function EditorsSideMenu() {
<EditorsSideMenuItem view={EditorView.SEGMENT} label="Segment editor">
<IoFilmOutline />
</EditorsSideMenuItem>

{/*<EditorSideMenuItem name="Characters"><LiaTheaterMasksSolid /></EditorSideMenuItem>*/}
{/*<EditorSideMenuItem name="Project"><MdLocalMovies /></EditorSideMenuItem>*/}
{/*<EditorSideMenuItem name="Locations"><TbMapSearch /></EditorSideMenuItem> */}

{/*<EditorSideMenuItem name="Assistant" label="Movie assistant"><MdAutoFixHigh /></EditorSideMenuItem>*}
{/*<EditorSideMenuItem name="Rendering"><IoFilmOutline /></EditorSideMenuItem>*/}
{/*<EditorSideMenuItem name="Export"><HiOutlineCloudArrowDown /></EditorSideMenuItem>*/}
{/*<EditorSideMenuItem name="Broadcast"><BsBroadcastPin /></EditorSideMenuItem>*/}
<EditorsSideMenuItem view={EditorView.WORKFLOW} label="Workflow editor">
<PiTreeStructureBold />
</EditorsSideMenuItem>
</div>
</div>
)
Expand Down
8 changes: 8 additions & 0 deletions src/components/tree-browsers/stores/treeNodeStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// TODO: this isn't the best place for this as this is style,
// and we are in a state manager
export const libraryClassName = 'text-base font-semibold'

export const collectionClassName = `text-base font-normal`

export const itemClassName =
'text-sm font-light text-gray-200/60 hover:text-gray-200/100'
14 changes: 5 additions & 9 deletions src/components/tree-browsers/stores/useEntityLibrary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,11 @@ import {
} from '../types'
import { icons } from '@/components/icons'
import { getAppropriateIcon } from '@/components/icons/getAppropriateIcon'

// TODO: this isn't the best place for this as this is style,
// and we are in a state manager
const libraryClassName = 'text-base font-semibold'

const collectionClassName = `text-base font-normal`

const itemClassName =
'text-sm font-light text-gray-200/60 hover:text-gray-200/100'
import {
collectionClassName,
itemClassName,
libraryClassName,
} from './treeNodeStyles'

export const useEntityLibrary = create<{
teamLibraryTreeNodeId: string
Expand Down
9 changes: 1 addition & 8 deletions src/components/tree-browsers/stores/useFileLibrary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,7 @@ import { icons } from "@/components/icons"
import { getAppropriateIcon } from "@/components/icons/getAppropriateIcon"
import { className } from "@/app/fonts"
import { getCollectionItemTextColor } from "../utils/getCollectionItemTextColor"

// TODO: this isn't the best place for this as this is style,
// and we are in a state manager
const libraryClassName = "text-base font-semibold"

const collectionClassName = `text-base font-normal`

const itemClassName = "text-sm font-light text-gray-200/60 hover:text-gray-200/100"
import { collectionClassName, itemClassName, libraryClassName } from './treeNodeStyles'

export const useFileLibrary = create<{
localUserLibraryTreeNodeId: string
Expand Down
14 changes: 5 additions & 9 deletions src/components/tree-browsers/stores/useProjectLibrary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@ import { ClapEntity, ClapSegmentCategory, UUID } from '@aitube/clap'
import { icons } from '@/components/icons'

import { LibraryNodeItem, LibraryNodeType, LibraryTreeNode } from '../types'

// TODO: this isn't the best place for this as this is style,
// and we are in a state manager
const libraryClassName = 'text-base font-semibold'

const collectionClassName = `text-base font-normal`

const itemClassName =
'text-sm font-light text-gray-200/60 hover:text-gray-200/100'
import {
collectionClassName,
itemClassName,
libraryClassName,
} from './treeNodeStyles'

export const useProjectLibrary = create<{
libraryTreeRoot: LibraryTreeNode[]
Expand Down
124 changes: 124 additions & 0 deletions src/components/tree-browsers/stores/useWorkflowLibrary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
'use client'

import { create } from 'zustand'
import { ClapEntity, UUID } from '@aitube/clap'
import { LibraryNodeItem, LibraryNodeType, LibraryTreeNode } from '../types'
import { icons } from '@/components/icons'
import { collectionClassName, libraryClassName } from './treeNodeStyles'

export const useWorkflowLibrary = create<{
builtInLibraryTreeNodeId: string
communityLibraryTreeNodeId: string
libraryTreeRoot: LibraryTreeNode[]
init: () => void

/**
* Load built-in collections into the tree
*
* @param collections
* @returns
*/
//setBuiltInCollections: (collections: WorkflowCollection[]) => void

/**
* Load community collections into the tree
*
* @param collections
* @returns
*/
//setCommunityCollections: (collections: WorkflowCollection[]) => void

// we support those all selection modes for convenience - please keep them!
selectedNodeItem?: LibraryNodeItem
selectedNodeType?: LibraryNodeType
selectTreeNode: (
treeNodeId?: string | null,
nodeType?: LibraryNodeType,
nodeItem?: LibraryNodeItem
) => void
selectedTreeNodeId: string | null
}>((set, get) => ({
builtInLibraryTreeNodeId: '',
communityLibraryTreeNodeId: '',
libraryTreeRoot: [],
init: () => {
const builtInLibrary: LibraryTreeNode = {
id: UUID(),
nodeType: 'LIB_NODE_WORKFLOWS',
label: 'Built-in workflows',
icon: icons.project,
className: libraryClassName,
isExpanded: true,
children: [
{
id: UUID(),
nodeType: 'LIB_NODE_GENERIC_EMPTY',
label: 'A - 2',
icon: icons.project,
className: collectionClassName,
},
],
}

const communityLibrary: LibraryTreeNode = {
id: UUID(),
nodeType: 'LIB_NODE_COMMUNITY_COLLECTION',
label: 'Community workflows',
icon: icons.community,
className: libraryClassName,
children: [
{
id: UUID(),
nodeType: 'LIB_NODE_GENERIC_EMPTY',
label: 'A - 2',
icon: icons.community,
className: collectionClassName,
},
],
}

const libraryTreeRoot = [builtInLibrary, communityLibrary]

set({
builtInLibraryTreeNodeId: builtInLibrary.id,
communityLibraryTreeNodeId: communityLibrary.id,
libraryTreeRoot,
selectedNodeItem: undefined,
selectedTreeNodeId: null,
})
},

selectedNodeItem: undefined,
selectEntity: (entity?: ClapEntity) => {
if (entity) {
console.log(
'TODO julian: change this code to search in the entity collections'
)
const selectedTreeNode = get().libraryTreeRoot.find(
(node) => node.data?.id === entity.id
)

// set({ selectedTreeNode })
set({ selectedTreeNodeId: selectedTreeNode?.id || null })
set({ selectedNodeItem: entity })
} else {
// set({ selectedTreeNode: undefined })
set({ selectedTreeNodeId: null })
set({ selectedNodeItem: undefined })
}
},

// selectedTreeNode: undefined,
selectedTreeNodeId: null,
selectTreeNode: (
treeNodeId?: string | null,
nodeType?: LibraryNodeType,
nodeItem?: LibraryNodeItem
) => {
set({ selectedTreeNodeId: treeNodeId ? treeNodeId : undefined })
set({ selectedNodeType: nodeType ? nodeType : undefined })
set({ selectedNodeItem: nodeItem ? nodeItem : undefined })
},
}))

useWorkflowLibrary.getState().init()
49 changes: 34 additions & 15 deletions src/components/tree-browsers/types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
// note: we only keep simplified representations of provider data structures

import { ScreenplaySequence } from '@aitube/broadway'
import { ClapEntity, ClapSegment } from '@aitube/clap'
import { ClapEntity, ClapSegment, ClapWorkflow } from '@aitube/clap'
import { TreeNodeType } from '../core/tree/types'

// not sure if we should also sort them into data type categories,
// as vendors like to be on multiple kind of models

export type LibraryNodeHuggingFaceType =
| 'LIB_NODE_HUGGINGFACE_USER_COLLECTION'
| 'LIB_NODE_HUGGINGFACE_USER_DATASET'

export type LibraryNodeLocalFileType =
| 'LIB_NODE_LOCAL_USER_FILE'
| 'LIB_NODE_LOCAL_USER_FOLDER'
Expand All @@ -19,25 +23,34 @@ export type LibraryNodeFileType =
| LibraryNodeLocalFileType
| LibraryNodeRemoteFileType

export type LibraryNodeWorkflowType = 'LIB_NODE_WORKFLOWS' | 'LIB_NODE_WORKFLOW'

export type LibraryNodeProjectType =
| 'LIB_NODE_PROJECT_COLLECTION'
| 'LIB_NODE_PROJECT_ARCHIVE'
| 'LIB_NODE_PROJECT_ASSET' // image, sound file..
| 'LIB_NODE_PROJECT_ENTITY_GENERIC'
| 'LIB_NODE_PROJECT_ENTITY_CHARACTER'
| 'LIB_NODE_PROJECT_ENTITY_LOCATION'

export type LibraryNodeGenericType =
| 'LIB_NODE_GENERIC_COLLECTION'
| 'LIB_NODE_GENERIC_MODEL'
| 'LIB_NODE_GENERIC_ITEM'
| 'LIB_NODE_GENERIC_EMPTY'

/**
* a collection always correspond to the root category displayed in the tree menu
*
* we could use "LIB_NODE_GENERIC_COLLECTION",
* but I think it can also be useful to keep specific types,
* that way we can show a custom collection UI panel on the right of the explorer
*/
export type LibraryNodeType =
| 'LIB_NODE_LOCAL_USER_COLLECTION'
| LibraryNodeLocalFileType
| 'LIB_NODE_HUGGINGFACE_USER_COLLECTION'
| 'LIB_NODE_HUGGINGFACE_USER_DATASET'
| LibraryNodeHuggingFaceType
| LibraryNodeRemoteFileType
| 'LIB_NODE_PROJECT_COLLECTION'
| 'LIB_NODE_PROJECT_ARCHIVE'
| 'LIB_NODE_PROJECT_ASSET' // image, sound file..
| 'LIB_NODE_PROJECT_ENTITY_GENERIC'
| 'LIB_NODE_PROJECT_ENTITY_CHARACTER'
| 'LIB_NODE_PROJECT_ENTITY_LOCATION'
| LibraryNodeWorkflowType
| LibraryNodeProjectType
| 'LIB_NODE_TEAM_COLLECTION'
| 'LIB_NODE_TEAM_MODEL'
| 'LIB_NODE_COMMUNITY_COLLECTION'
Expand All @@ -48,10 +61,7 @@ export type LibraryNodeType =
| 'LIB_NODE_REPLICATE_MODEL'
| 'LIB_NODE_CIVITAI_COLLECTION'
| 'LIB_NODE_CIVITAI_MODEL'
| 'LIB_NODE_GENERIC_COLLECTION'
| 'LIB_NODE_GENERIC_MODEL'
| 'LIB_NODE_GENERIC_ITEM'
| 'LIB_NODE_GENERIC_EMPTY'
| LibraryNodeGenericType

// can be a file or folder
export type LocalUserItem = {
Expand Down Expand Up @@ -140,6 +150,13 @@ export type CivitaiCollection = {
models: CivitaiModel[]
}

export type WorkflowCollection = {
id: string
name: string
description: string
workflows: ClapWorkflow[]
}

// TODO unify this a bit, at least in the naming scheme
export type LibraryNodeFileItem = LocalUserItem | HuggingFaceUserItem

Expand All @@ -156,6 +173,8 @@ export type LibraryNodeItem =
| HuggingFaceUserItem
| ScreenplaySequence
| ClapSegment
| WorkflowCollection
| ClapWorkflow

// a model library is a collection of models
// this collection can itself include sub-models
Expand Down
Loading

0 comments on commit a54bba5

Please sign in to comment.