Skip to content
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

feat: enhance properties #5

Merged
merged 2 commits into from
Aug 25, 2024
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
77 changes: 76 additions & 1 deletion src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,25 @@ export const isNumberType = (type: PropertyType): boolean => {
type === "float32" || type === "float64"
}

export const getZeroValue = (type: InputType) => {
export const getInputTypeByPropertyType = (type: PropertyType): InputType => {
if (type === "string") {
return "string"
} else if (isNumberType(type)) {
return "number"
} else if (type === "bool") {
return "boolean"
}

return "string"
}

export const getDefaultValueByPropertyType = (type: PropertyType) => {
let inputType = getInputTypeByPropertyType(type)
return getDefaultValueByInputType(inputType)
}


export const getDefaultValueByInputType = (type: InputType) => {
if (type === "number") {
return 0
} else if (type === "boolean") {
Expand Down Expand Up @@ -432,6 +450,63 @@ export const edgesToConnections = (
}
}

// merge dests
connections = connections.map((connection) => {
const { cmd, data, audio_frame, video_frame } = connection
const finalConnection: IConnection = {
...connection,
}
if (cmd?.length) {
finalConnection.cmd = cmd.reduce((acc, curr) => {
const { name, dest } = curr
const temp = acc.find((i) => i.name == name)
if (temp) {
temp.dest.push(...dest)
} else {
acc.push(curr)
}
return acc
}, [] as IConnectionData[])
}
if (data?.length) {
finalConnection.data = data.reduce((acc, curr) => {
const { name, dest } = curr
const temp = acc.find((i) => i.name == name)
if (temp) {
temp.dest.push(...dest)
} else {
acc.push(curr)
}
return acc
}, [] as IConnectionData[])
}
if (audio_frame?.length) {
finalConnection.audio_frame = audio_frame.reduce((acc, curr) => {
const { name, dest } = curr
const temp = acc.find((i) => i.name == name)
if (temp) {
temp.dest.push(...dest)
} else {
acc.push(curr)
}
return acc
}, [] as IConnectionData[])
}
if (video_frame?.length) {
finalConnection.video_frame = video_frame.reduce((acc, curr) => {
const { name, dest } = curr
const temp = acc.find((i) => i.name == name)
if (temp) {
temp.dest.push(...dest)
} else {
acc.push(curr)
}
return acc
}, [] as IConnectionData[])
}
return finalConnection
})

return connections
}

Expand Down
1 change: 1 addition & 0 deletions src/components/editor/flow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ const Flow = () => {
logger.debug("saveFlow nodes:", nodes)
logger.debug("saveFlow edges:", edges)
const extensions = nodesToExtensions(nodes, installedExtensions)
// const extensionGroups =
const connections = edgesToConnections(edges, nodes)
logger.debug("saveFlow extensions:", extensions)
logger.debug("saveFlow connections:", connections)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@

}

.menuItem {
margin: 5px !important;
}

.contentSection {
width: 220px;
max-height: 300px;
padding: 10px 20px;
overflow-y: auto;
overflow-x: hidden;

Expand Down
86 changes: 71 additions & 15 deletions src/components/editor/flow/nodes/propertySection/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Popover, Input } from 'antd';
import { Popover, Input, Form, Checkbox, Button, Card, Select, Dropdown, Typography, Space, MenuProps } from 'antd';
import { IExtensionProperty, IExtensionPropertyTypes } from "@/types"
import PropertyItem from "./item"
import { EditOutlined } from "@ant-design/icons"
import { DownOutlined, EditOutlined, PlusOutlined } from "@ant-design/icons"
import styles from "./index.module.scss"
import { useMemo } from 'react';
import { useMemo, useState } from 'react';
import { getDefaultValueByPropertyType } from '@/common';


interface PropertySectionProps {
Expand All @@ -19,22 +20,77 @@ const PropertySection = (props: PropertySectionProps) => {
return propertyTypes ? Object.keys(propertyTypes).sort((a: string, b: string) => a > b ? 1 : -1) : []
}, [propertyTypes])

const propertiesMenu = useMemo(() => {
return propertyKeyList.map((key, index) => {
return {
key: key,
label: key,
className: styles.menuItem,
}
})
}, [propertyKeyList])

const availableProperties = useMemo(() => {
return propertyTypes ? propertyKeyList.filter(key => property?.[key] !== undefined) : []
}, [property, propertyKeyList])

const content = (
<div className={styles.contentSection}>
{propertyKeyList.map((key, index) => {
return <PropertyItem
value={property?.[key]}
key={index}
name={key}
propertyType={propertyTypes?.[key].type}
onUpdate={value => onUpdate?.(key, value)}></PropertyItem>
})}
</div>
<Card
title="Properties"
extra={(
<Dropdown
overlayStyle={{maxHeight: 400, overflow: 'auto'}}
menu={{
items: propertiesMenu,
defaultSelectedKeys: Object.keys(property || {}),
multiple: true,
selectable: true,
onSelect: ({key}) => {
if (propertyTypes && propertyTypes?.[key]) {
onUpdate?.(key, getDefaultValueByPropertyType(propertyTypes[key].type))
}
},
onDeselect: ({key}) => {
onUpdate?.(key, undefined)
}
}}
>
<Typography.Link>
<Space>
Edit Properties
<DownOutlined />
</Space>
</Typography.Link>
</Dropdown>
)}
bordered={false}
styles={{body: {padding: 0}}}
>
<Form
name="basic"
layout='vertical'
className={styles.contentSection}
wrapperCol={{ flex: 1 }}
initialValues={{ remember: true }}
onFinish={() =>{}}
onFinishFailed={() =>{}}
autoComplete="off"
>
{availableProperties.map((key, index) => {
return <PropertyItem
value={property?.[key]}
key={index}
name={key}
propertyType={propertyTypes?.[key]?.type}
onUpdate={value => onUpdate?.(key, value)}></PropertyItem>
})}
</Form>
</Card>
);

return property ? <div className={styles.property} >
return propertyKeyList.length > 0 ? <div className={styles.property} >
<span className={styles.title}>property</span>
<Popover content={content} rootClassName={styles.propertyPopover}>
<Popover overlayInnerStyle={{padding:0}} content={content} rootClassName={styles.propertyPopover} trigger={"click"}>
<EditOutlined></EditOutlined>
</Popover>
</div > : <></>
Expand Down
12 changes: 4 additions & 8 deletions src/components/editor/flow/nodes/propertySection/item/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo, useState } from "react"
import { Input, Switch, InputNumber, message } from "antd"
import { getZeroValue, hasDecimalPoint, isNumberType } from "@/common"
import { Input, Switch, InputNumber, message, Form } from "antd"
import { getDefaultValueByInputType, hasDecimalPoint, isNumberType } from "@/common"
import { PropertyType, InputType } from "@/types"

import styles from "./index.module.scss"
Expand Down Expand Up @@ -46,7 +46,7 @@ const checkValue = (value: any, propertyType: PropertyType, inputType: InputType


const CustomInput = (CustomInputProps: CustomInputProps) => {
const { propertyType, value: propsValue, onUpdate } = CustomInputProps
const { propertyType, value: propsValue, onUpdate, name } = CustomInputProps
const [value, setValue] = useState(propsValue)
const [status, setStatus] = useState<Status>("")

Expand All @@ -71,7 +71,7 @@ const CustomInput = (CustomInputProps: CustomInputProps) => {
}
if (checkValue(value, propertyType, inputType)) {
if (value === null || value === undefined) {
value = getZeroValue(inputType)
value = getDefaultValueByInputType(inputType)
}
setValue(value)
setStatus("")
Expand All @@ -95,7 +95,6 @@ const CustomInput = (CustomInputProps: CustomInputProps) => {

if (inputType === "string") {
return <Input
size="small"
value={value}
allowClear
status={status}
Expand All @@ -104,17 +103,14 @@ const CustomInput = (CustomInputProps: CustomInputProps) => {
></Input>
} else if (inputType === "number") {
return <InputNumber
size="small"
value={value}
type='number'
status={status}
onChange={onChange}
onBlur={onBlur}
style={{ width: "100%" }}
></InputNumber>
} else if (inputType === "boolean") {
return <Switch
size="small"
value={value}
onChange={onChange}></Switch>
}
Expand Down