feat: model load balancing (#4926)

This commit is contained in:
Nite Knite
2024-06-05 00:13:29 +08:00
committed by GitHub
parent d1dbbc1e33
commit 37f292ea91
58 changed files with 1896 additions and 304 deletions

View File

@ -3,10 +3,10 @@
@layer components {
.btn {
@apply inline-flex justify-center items-center content-center h-9 leading-5 rounded-lg px-4 py-2 text-base cursor-pointer whitespace-nowrap;
}
};
.btn-default {
@apply border-solid border border-gray-200 cursor-pointer text-gray-500 hover:bg-white hover:shadow-sm hover:border-gray-300;
@apply border-solid border border-gray-200 cursor-pointer text-gray-700 hover:bg-white hover:shadow-sm hover:border-gray-300;
}
.btn-default-disabled {
@ -28,4 +28,4 @@
.btn-warning-disabled {
@apply bg-red-600/75 cursor-not-allowed text-white;
}
}
}

View File

@ -1,16 +1,16 @@
import type { FC, MouseEventHandler } from 'react'
import React from 'react'
import type { FC, MouseEventHandler, PropsWithChildren } from 'react'
import React, { memo } from 'react'
import classNames from 'classnames'
import Spinner from '../spinner'
export type IButtonProps = {
export type IButtonProps = PropsWithChildren<{
type?: string
className?: string
disabled?: boolean
loading?: boolean
tabIndex?: number
children: React.ReactNode
onClick?: MouseEventHandler<HTMLDivElement>
}
}>
const Button: FC<IButtonProps> = ({
type,
@ -21,22 +21,22 @@ const Button: FC<IButtonProps> = ({
loading = false,
tabIndex,
}) => {
let style = 'cursor-pointer'
let typeClassNames = 'cursor-pointer'
switch (type) {
case 'primary':
style = (disabled || loading) ? 'btn-primary-disabled' : 'btn-primary'
typeClassNames = (disabled || loading) ? 'btn-primary-disabled' : 'btn-primary'
break
case 'warning':
style = (disabled || loading) ? 'btn-warning-disabled' : 'btn-warning'
typeClassNames = (disabled || loading) ? 'btn-warning-disabled' : 'btn-warning'
break
default:
style = disabled ? 'btn-default-disabled' : 'btn-default'
typeClassNames = disabled ? 'btn-default-disabled' : 'btn-default'
break
}
return (
<div
className={`btn ${style} ${className && className}`}
className={classNames('btn', typeClassNames, className)}
tabIndex={tabIndex}
onClick={disabled ? undefined : onClick}
>
@ -47,4 +47,4 @@ const Button: FC<IButtonProps> = ({
)
}
export default React.memo(Button)
export default memo(Button)

View File

@ -65,7 +65,7 @@ const WorkflowProcessItem = ({
return (
<div
className={cn(
'mb-2 rounded-xl border-[0.5px] border-black/[0.08]',
'mb-2 rounded-xl border-[0.5px] border-black/8',
collapse ? 'py-[7px]' : hideInfo ? 'pt-2 pb-1' : 'py-2',
collapse && (!grayBg ? 'bg-white' : 'bg-gray-50'),
hideInfo ? 'mx-[-8px] px-1' : 'w-full px-3',

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 3V20M12 20H6.99999M12 20H17M2.99999 6H7.52785C7.83834 6 8.14457 5.92771 8.42228 5.78885L9.5777 5.21115C9.85541 5.07229 10.1616 5 10.4721 5H13.5279C13.8384 5 14.1446 5.07229 14.4223 5.21115L15.5777 5.78885C15.8554 5.92771 16.1616 6 16.4721 6H21M5.49999 6L3.02043 13.4387C2.71807 14.3458 3.08918 15.3834 4.0053 15.657C5.0117 15.9577 5.98828 15.9577 6.99468 15.657C7.9108 15.3834 8.28191 14.3457 7.97955 13.4387L5.49999 6ZM18.5 6L16.0204 13.4387C15.7181 14.3458 16.0892 15.3834 17.0053 15.657C18.0117 15.9577 18.9883 15.9577 19.9947 15.657C20.9108 15.3834 21.2819 14.3457 20.9796 13.4387L18.5 6Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 791 B

View File

@ -0,0 +1,29 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M12 3V20M12 20H6.99999M12 20H17M2.99999 6H7.52785C7.83834 6 8.14457 5.92771 8.42228 5.78885L9.5777 5.21115C9.85541 5.07229 10.1616 5 10.4721 5H13.5279C13.8384 5 14.1446 5.07229 14.4223 5.21115L15.5777 5.78885C15.8554 5.92771 16.1616 6 16.4721 6H21M5.49999 6L3.02043 13.4387C2.71807 14.3458 3.08918 15.3834 4.0053 15.657C5.0117 15.9577 5.98828 15.9577 6.99468 15.657C7.9108 15.3834 8.28191 14.3457 7.97955 13.4387L5.49999 6ZM18.5 6L16.0204 13.4387C15.7181 14.3458 16.0892 15.3834 17.0053 15.657C18.0117 15.9577 18.9883 15.9577 19.9947 15.657C20.9108 15.3834 21.2819 14.3457 20.9796 13.4387L18.5 6Z",
"stroke": "currentColor",
"stroke-width": "2",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
},
"name": "Balance"
}

View File

@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Balance.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
Icon.displayName = 'Balance'
export default Icon

View File

@ -1,3 +1,4 @@
export { default as Balance } from './Balance'
export { default as CoinsStacked01 } from './CoinsStacked01'
export { default as GoldCoin } from './GoldCoin'
export { default as ReceiptList } from './ReceiptList'

View File

@ -77,8 +77,7 @@ const ImageList: FC<ImageListProps> = ({
<div
className={`
absolute inset-0 flex items-center justify-center rounded-lg z-[1] border
${
item.progress === -1
${item.progress === -1
? 'bg-[#FEF0C7] border-[#DC6803]'
: 'bg-black/[0.16] border-transparent'
}
@ -120,7 +119,7 @@ const ImageList: FC<ImageListProps> = ({
type="button"
className={cn(
'absolute z-10 -top-[9px] -right-[9px] items-center justify-center w-[18px] h-[18px]',
'bg-white hover:bg-gray-50 border-[0.5px] border-black/[0.02] rounded-2xl shadow-lg',
'bg-white hover:bg-gray-50 border-[0.5px] border-black/2 rounded-2xl shadow-lg',
item.progress === -1 ? 'flex' : 'hidden group-hover:flex',
)}
onClick={() => onRemove && onRemove(item._id)}

View File

@ -18,7 +18,7 @@ const ImagePreview: FC<ImagePreviewProps> = ({
className='max-w-full max-h-full'
/>
<div
className='absolute top-6 right-6 flex items-center justify-center w-8 h-8 bg-white/[0.08] rounded-lg backdrop-blur-[2px] cursor-pointer'
className='absolute top-6 right-6 flex items-center justify-center w-8 h-8 bg-white/8 rounded-lg backdrop-blur-[2px] cursor-pointer'
onClick={onCancel}
>
<XClose className='w-4 h-4 text-white' />

View File

@ -0,0 +1,7 @@
.modal-dialog {
@apply relative z-10;
}
.modal-panel {
@apply w-full max-w-md transform rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all;
}

View File

@ -1,16 +1,17 @@
import { Dialog, Transition } from '@headlessui/react'
import { Fragment } from 'react'
import { XMarkIcon } from '@heroicons/react/24/outline'
import classNames from 'classnames'
// https://headlessui.com/react/dialog
type IModal = {
className?: string
wrapperClassName?: string
isShow: boolean
onClose: () => void
onClose?: () => void
title?: React.ReactNode
description?: React.ReactNode
children: React.ReactNode
children?: React.ReactNode
closable?: boolean
overflowVisible?: boolean
}
@ -19,7 +20,7 @@ export default function Modal({
className,
wrapperClassName,
isShow,
onClose,
onClose = () => { },
title,
description,
children,
@ -28,7 +29,7 @@ export default function Modal({
}: IModal) {
return (
<Transition appear show={isShow} as={Fragment}>
<Dialog as="div" className={`relative z-30 ${wrapperClassName}`} onClose={onClose}>
<Dialog as="div" className={classNames('modal-dialog', wrapperClassName)} onClose={onClose}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
@ -58,7 +59,11 @@ export default function Modal({
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className={`w-full max-w-md transform ${overflowVisible ? 'overflow-visible' : 'overflow-hidden'} rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all ${className}`}>
<Dialog.Panel className={classNames(
'modal-panel',
overflowVisible ? 'overflow-visible' : 'overflow-hidden',
className,
)}>
{title && <Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900"

View File

@ -0,0 +1,4 @@
.simplePieChart {
border-radius: 50%;
box-shadow: 0 0 5px -3px rgb(from var(--simple-pie-chart-color) r g b / 0.1), 0.5px 0.5px 3px 0 rgb(from var(--simple-pie-chart-color) r g b / 0.3);
}

View File

@ -0,0 +1,66 @@
import type { CSSProperties } from 'react'
import { memo, useMemo } from 'react'
import ReactECharts from 'echarts-for-react'
import type { EChartsOption } from 'echarts'
import classNames from 'classnames'
import style from './index.module.css'
export type SimplePieChartProps = {
percentage?: number
fill?: string
stroke?: string
size?: number
className?: string
}
const SimplePieChart = ({ percentage = 80, fill = '#fdb022', stroke = '#f79009', size = 12, className }: SimplePieChartProps) => {
const option: EChartsOption = useMemo(() => ({
series: [
{
type: 'pie',
radius: ['83%', '100%'],
animation: false,
data: [
{ value: 100, itemStyle: { color: stroke } },
],
emphasis: {
disabled: true,
},
labelLine: {
show: false,
},
cursor: 'default',
},
{
type: 'pie',
radius: '83%',
animationDuration: 600,
data: [
{ value: percentage, itemStyle: { color: fill } },
{ value: 100 - percentage, itemStyle: { color: '#fff' } },
],
emphasis: {
disabled: true,
},
labelLine: {
show: false,
},
cursor: 'default',
},
],
}), [stroke, fill, percentage])
return (
<ReactECharts
option={option}
className={classNames(style.simplePieChart, className)}
style={{
'--simple-pie-chart-color': fill,
'width': size,
'height': size,
} as CSSProperties}
/>
)
}
export default memo(SimplePieChart)

View File

@ -4,13 +4,14 @@ import classNames from 'classnames'
import { Switch as OriginalSwitch } from '@headlessui/react'
type SwitchProps = {
onChange: (value: boolean) => void
onChange?: (value: boolean) => void
size?: 'sm' | 'md' | 'lg' | 'l'
defaultValue?: boolean
disabled?: boolean
className?: string
}
const Switch = ({ onChange, size = 'lg', defaultValue = false, disabled = false }: SwitchProps) => {
const Switch = ({ onChange, size = 'lg', defaultValue = false, disabled = false, className }: SwitchProps) => {
const [enabled, setEnabled] = useState(defaultValue)
useEffect(() => {
setEnabled(defaultValue)
@ -42,13 +43,14 @@ const Switch = ({ onChange, size = 'lg', defaultValue = false, disabled = false
if (disabled)
return
setEnabled(checked)
onChange(checked)
onChange?.(checked)
}}
className={classNames(
wrapStyle[size],
enabled ? 'bg-blue-600' : 'bg-gray-200',
'relative inline-flex flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out',
disabled ? '!opacity-50 !cursor-not-allowed' : '',
className,
)}
>
<span