feat: introduce trigger functionality (#27644)
Signed-off-by: lyzno1 <yuanyouhuilyz@gmail.com> Co-authored-by: Stream <Stream_2@qq.com> Co-authored-by: lyzno1 <92089059+lyzno1@users.noreply.github.com> Co-authored-by: zhsama <torvalds@linux.do> Co-authored-by: Harry <xh001x@hotmail.com> Co-authored-by: lyzno1 <yuanyouhuilyz@gmail.com> Co-authored-by: yessenia <yessenia.contact@gmail.com> Co-authored-by: hjlarry <hjlarry@163.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: WTW0313 <twwu@dify.ai> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -16,6 +16,7 @@ import cn from '@/utils/classnames'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { Plan } from '@/app/components/billing/type'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
import { getDocDownloadUrl } from '@/service/common'
|
||||
|
||||
enum DocName {
|
||||
@@ -38,7 +39,7 @@ const UpgradeOrDownload: FC<UpgradeOrDownloadProps> = ({ doc_name }) => {
|
||||
if (isFreePlan)
|
||||
setShowPricingModal()
|
||||
else
|
||||
setShowAccountSettingModal({ payload: 'billing' })
|
||||
setShowAccountSettingModal({ payload: ACCOUNT_SETTING_TAB.BILLING })
|
||||
}, [isFreePlan, setShowAccountSettingModal, setShowPricingModal])
|
||||
|
||||
const { isPending, mutate: downloadCompliance } = useMutation({
|
||||
|
||||
@@ -33,6 +33,7 @@ import cn from '@/utils/classnames'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useDocLink } from '@/context/i18n'
|
||||
import { useLogout } from '@/service/use-common'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
|
||||
export default function AppSelector() {
|
||||
const itemClassName = `
|
||||
@@ -122,7 +123,7 @@ export default function AppSelector() {
|
||||
<MenuItem>
|
||||
<div className={cn(itemClassName,
|
||||
'data-[active]:bg-state-base-hover',
|
||||
)} onClick={() => setShowAccountSettingModal({ payload: 'members' })}>
|
||||
)} onClick={() => setShowAccountSettingModal({ payload: ACCOUNT_SETTING_TAB.MEMBERS })}>
|
||||
<RiSettings3Line className='size-4 shrink-0 text-text-tertiary' />
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.settings')}</div>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
} from '@/app/components/base/icons/src/vender/line/arrows'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { fetchApiBasedExtensionList } from '@/service/common'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
|
||||
type ApiBasedExtensionSelectorProps = {
|
||||
value: string
|
||||
@@ -83,7 +84,7 @@ const ApiBasedExtensionSelector: FC<ApiBasedExtensionSelectorProps> = ({
|
||||
className='flex cursor-pointer items-center text-xs text-text-accent'
|
||||
onClick={() => {
|
||||
setOpen(false)
|
||||
setShowAccountSettingModal({ payload: 'api-based-extension' })
|
||||
setShowAccountSettingModal({ payload: ACCOUNT_SETTING_TAB.API_BASED_EXTENSION })
|
||||
}}
|
||||
>
|
||||
{t('common.apiBasedExtension.selector.manage')}
|
||||
|
||||
21
web/app/components/header/account-setting/constants.ts
Normal file
21
web/app/components/header/account-setting/constants.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export const ACCOUNT_SETTING_MODAL_ACTION = 'showSettings'
|
||||
|
||||
export const ACCOUNT_SETTING_TAB = {
|
||||
PROVIDER: 'provider',
|
||||
MEMBERS: 'members',
|
||||
BILLING: 'billing',
|
||||
DATA_SOURCE: 'data-source',
|
||||
API_BASED_EXTENSION: 'api-based-extension',
|
||||
CUSTOM: 'custom',
|
||||
LANGUAGE: 'language',
|
||||
} as const
|
||||
|
||||
export type AccountSettingTab = typeof ACCOUNT_SETTING_TAB[keyof typeof ACCOUNT_SETTING_TAB]
|
||||
|
||||
export const DEFAULT_ACCOUNT_SETTING_TAB = ACCOUNT_SETTING_TAB.MEMBERS
|
||||
|
||||
export const isValidAccountSettingTab = (tab: string | null): tab is AccountSettingTab => {
|
||||
if (!tab)
|
||||
return false
|
||||
return Object.values(ACCOUNT_SETTING_TAB).includes(tab as AccountSettingTab)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
useMarketplacePlugins,
|
||||
} from '@/app/components/plugins/marketplace/hooks'
|
||||
import type { Plugin } from '@/app/components/plugins/types'
|
||||
import { PluginType } from '@/app/components/plugins/types'
|
||||
import { PluginCategoryEnum } from '@/app/components/plugins/types'
|
||||
import { getMarketplacePluginsByCollectionId } from '@/app/components/plugins/marketplace/utils'
|
||||
|
||||
export const useMarketplaceAllPlugins = (providers: any[], searchText: string) => {
|
||||
@@ -38,7 +38,7 @@ export const useMarketplaceAllPlugins = (providers: any[], searchText: string) =
|
||||
if (searchText) {
|
||||
queryPluginsWithDebounced({
|
||||
query: searchText,
|
||||
category: PluginType.datasource,
|
||||
category: PluginCategoryEnum.datasource,
|
||||
exclude,
|
||||
type: 'plugin',
|
||||
sortBy: 'install_count',
|
||||
@@ -48,7 +48,7 @@ export const useMarketplaceAllPlugins = (providers: any[], searchText: string) =
|
||||
else {
|
||||
queryPlugins({
|
||||
query: '',
|
||||
category: PluginType.datasource,
|
||||
category: PluginCategoryEnum.datasource,
|
||||
type: 'plugin',
|
||||
pageSize: 1000,
|
||||
exclude,
|
||||
|
||||
@@ -31,6 +31,10 @@ import { useProviderContext } from '@/context/provider-context'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import MenuDialog from '@/app/components/header/account-setting/menu-dialog'
|
||||
import Input from '@/app/components/base/input'
|
||||
import {
|
||||
ACCOUNT_SETTING_TAB,
|
||||
type AccountSettingTab,
|
||||
} from '@/app/components/header/account-setting/constants'
|
||||
|
||||
const iconClassName = `
|
||||
w-5 h-5 mr-2
|
||||
@@ -38,11 +42,12 @@ const iconClassName = `
|
||||
|
||||
type IAccountSettingProps = {
|
||||
onCancel: () => void
|
||||
activeTab?: string
|
||||
activeTab?: AccountSettingTab
|
||||
onTabChange?: (tab: AccountSettingTab) => void
|
||||
}
|
||||
|
||||
type GroupItem = {
|
||||
key: string
|
||||
key: AccountSettingTab
|
||||
name: string
|
||||
description?: string
|
||||
icon: React.JSX.Element
|
||||
@@ -51,56 +56,71 @@ type GroupItem = {
|
||||
|
||||
export default function AccountSetting({
|
||||
onCancel,
|
||||
activeTab = 'members',
|
||||
activeTab = ACCOUNT_SETTING_TAB.MEMBERS,
|
||||
onTabChange,
|
||||
}: IAccountSettingProps) {
|
||||
const [activeMenu, setActiveMenu] = useState(activeTab)
|
||||
const [activeMenu, setActiveMenu] = useState<AccountSettingTab>(activeTab)
|
||||
useEffect(() => {
|
||||
setActiveMenu(activeTab)
|
||||
}, [activeTab])
|
||||
const { t } = useTranslation()
|
||||
const { enableBilling, enableReplaceWebAppLogo } = useProviderContext()
|
||||
const { isCurrentWorkspaceDatasetOperator } = useAppContext()
|
||||
|
||||
const workplaceGroupItems = (() => {
|
||||
const workplaceGroupItems: GroupItem[] = (() => {
|
||||
if (isCurrentWorkspaceDatasetOperator)
|
||||
return []
|
||||
return [
|
||||
|
||||
const items: GroupItem[] = [
|
||||
{
|
||||
key: 'provider',
|
||||
key: ACCOUNT_SETTING_TAB.PROVIDER,
|
||||
name: t('common.settings.provider'),
|
||||
icon: <RiBrain2Line className={iconClassName} />,
|
||||
activeIcon: <RiBrain2Fill className={iconClassName} />,
|
||||
},
|
||||
{
|
||||
key: 'members',
|
||||
key: ACCOUNT_SETTING_TAB.MEMBERS,
|
||||
name: t('common.settings.members'),
|
||||
icon: <RiGroup2Line className={iconClassName} />,
|
||||
activeIcon: <RiGroup2Fill className={iconClassName} />,
|
||||
},
|
||||
{
|
||||
// Use key false to hide this item
|
||||
key: enableBilling ? 'billing' : false,
|
||||
]
|
||||
|
||||
if (enableBilling) {
|
||||
items.push({
|
||||
key: ACCOUNT_SETTING_TAB.BILLING,
|
||||
name: t('common.settings.billing'),
|
||||
description: t('billing.plansCommon.receiptInfo'),
|
||||
icon: <RiMoneyDollarCircleLine className={iconClassName} />,
|
||||
activeIcon: <RiMoneyDollarCircleFill className={iconClassName} />,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
items.push(
|
||||
{
|
||||
key: 'data-source',
|
||||
key: ACCOUNT_SETTING_TAB.DATA_SOURCE,
|
||||
name: t('common.settings.dataSource'),
|
||||
icon: <RiDatabase2Line className={iconClassName} />,
|
||||
activeIcon: <RiDatabase2Fill className={iconClassName} />,
|
||||
},
|
||||
{
|
||||
key: 'api-based-extension',
|
||||
key: ACCOUNT_SETTING_TAB.API_BASED_EXTENSION,
|
||||
name: t('common.settings.apiBasedExtension'),
|
||||
icon: <RiPuzzle2Line className={iconClassName} />,
|
||||
activeIcon: <RiPuzzle2Fill className={iconClassName} />,
|
||||
},
|
||||
{
|
||||
key: (enableReplaceWebAppLogo || enableBilling) ? 'custom' : false,
|
||||
)
|
||||
|
||||
if (enableReplaceWebAppLogo || enableBilling) {
|
||||
items.push({
|
||||
key: ACCOUNT_SETTING_TAB.CUSTOM,
|
||||
name: t('custom.custom'),
|
||||
icon: <RiColorFilterLine className={iconClassName} />,
|
||||
activeIcon: <RiColorFilterFill className={iconClassName} />,
|
||||
},
|
||||
].filter(item => !!item.key) as GroupItem[]
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
})()
|
||||
|
||||
const media = useBreakpoints()
|
||||
@@ -117,7 +137,7 @@ export default function AccountSetting({
|
||||
name: t('common.settings.generalGroup'),
|
||||
items: [
|
||||
{
|
||||
key: 'language',
|
||||
key: ACCOUNT_SETTING_TAB.LANGUAGE,
|
||||
name: t('common.settings.language'),
|
||||
icon: <RiTranslate2 className={iconClassName} />,
|
||||
activeIcon: <RiTranslate2 className={iconClassName} />,
|
||||
@@ -167,7 +187,10 @@ export default function AccountSetting({
|
||||
'mb-0.5 flex h-[37px] cursor-pointer items-center rounded-lg p-1 pl-3 text-sm',
|
||||
activeMenu === item.key ? 'system-sm-semibold bg-state-base-active text-components-menu-item-text-active' : 'system-sm-medium text-components-menu-item-text')}
|
||||
title={item.name}
|
||||
onClick={() => setActiveMenu(item.key)}
|
||||
onClick={() => {
|
||||
setActiveMenu(item.key)
|
||||
onTabChange?.(item.key)
|
||||
}}
|
||||
>
|
||||
{activeMenu === item.key ? item.activeIcon : item.icon}
|
||||
{!isMobile && <div className='truncate'>{item.name}</div>}
|
||||
|
||||
@@ -14,7 +14,8 @@ export enum FormTypeEnum {
|
||||
secretInput = 'secret-input',
|
||||
select = 'select',
|
||||
radio = 'radio',
|
||||
boolean = 'checkbox',
|
||||
checkbox = 'checkbox',
|
||||
boolean = 'boolean',
|
||||
files = 'files',
|
||||
file = 'file',
|
||||
modelSelector = 'model-selector',
|
||||
|
||||
@@ -35,7 +35,7 @@ import {
|
||||
useMarketplacePlugins,
|
||||
} from '@/app/components/plugins/marketplace/hooks'
|
||||
import type { Plugin } from '@/app/components/plugins/types'
|
||||
import { PluginType } from '@/app/components/plugins/types'
|
||||
import { PluginCategoryEnum } from '@/app/components/plugins/types'
|
||||
import { getMarketplacePluginsByCollectionId } from '@/app/components/plugins/marketplace/utils'
|
||||
import { useModalContextSelector } from '@/context/modal-context'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
@@ -278,7 +278,7 @@ export const useMarketplaceAllPlugins = (providers: ModelProvider[], searchText:
|
||||
if (searchText) {
|
||||
queryPluginsWithDebounced({
|
||||
query: searchText,
|
||||
category: PluginType.model,
|
||||
category: PluginCategoryEnum.model,
|
||||
exclude,
|
||||
type: 'plugin',
|
||||
sortBy: 'install_count',
|
||||
@@ -288,7 +288,7 @@ export const useMarketplaceAllPlugins = (providers: ModelProvider[], searchText:
|
||||
else {
|
||||
queryPlugins({
|
||||
query: '',
|
||||
category: PluginType.model,
|
||||
category: PluginCategoryEnum.model,
|
||||
type: 'plugin',
|
||||
pageSize: 1000,
|
||||
exclude,
|
||||
|
||||
@@ -264,7 +264,7 @@ function Form<
|
||||
)
|
||||
}
|
||||
|
||||
if (formSchema.type === FormTypeEnum.boolean) {
|
||||
if (formSchema.type === FormTypeEnum.checkbox) {
|
||||
const {
|
||||
variable, label, show_on, required,
|
||||
} = formSchema as CredentialFormSchemaRadio
|
||||
|
||||
@@ -36,7 +36,6 @@ export type ModelParameterModalProps = {
|
||||
popupClassName?: string
|
||||
portalToFollowElemContentClassName?: string
|
||||
isAdvancedMode: boolean
|
||||
mode: string
|
||||
modelId: string
|
||||
provider: string
|
||||
setModel: (model: { modelId: string; provider: string; mode?: string; features?: string[] }) => void
|
||||
|
||||
@@ -15,6 +15,7 @@ import { useLanguage } from '../hooks'
|
||||
import PopupItem from './popup-item'
|
||||
import { XCircle } from '@/app/components/base/icons/src/vender/solid/general'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
import { supportFunctionCall } from '@/utils/tool-call'
|
||||
import { tooltipManager } from '@/app/components/base/tooltip/TooltipManager'
|
||||
|
||||
@@ -129,7 +130,7 @@ const Popup: FC<PopupProps> = ({
|
||||
</div>
|
||||
<div className='sticky bottom-0 flex cursor-pointer items-center rounded-b-lg border-t border-divider-subtle bg-components-panel-bg px-4 py-2 text-text-accent-light-mode-only' onClick={() => {
|
||||
onHide()
|
||||
setShowAccountSettingModal({ payload: 'provider' })
|
||||
setShowAccountSettingModal({ payload: ACCOUNT_SETTING_TAB.PROVIDER })
|
||||
}}>
|
||||
<span className='system-xs-medium'>{t('common.model.settingsLink')}</span>
|
||||
<RiArrowRightUpLine className='ml-0.5 h-3 w-3' />
|
||||
|
||||
@@ -19,6 +19,7 @@ import CreateFromDSLModal from '@/app/components/app/create-from-dsl-modal'
|
||||
import type { AppListResponse } from '@/models/app'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
|
||||
const getKey = (
|
||||
pageIndex: number,
|
||||
@@ -79,7 +80,7 @@ const AppNav = () => {
|
||||
return `/app/${app.id}/overview`
|
||||
}
|
||||
else {
|
||||
if (app.mode === 'workflow' || app.mode === 'advanced-chat')
|
||||
if (app.mode === AppModeEnum.WORKFLOW || app.mode === AppModeEnum.ADVANCED_CHAT)
|
||||
return `/app/${app.id}/workflow`
|
||||
else
|
||||
return `/app/${app.id}/configuration`
|
||||
|
||||
@@ -19,6 +19,7 @@ import PlanBadge from './plan-badge'
|
||||
import LicenseNav from './license-env'
|
||||
import { Plan } from '../billing/type'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
|
||||
|
||||
const navClassName = `
|
||||
flex items-center relative px-3 h-8 rounded-xl
|
||||
@@ -38,7 +39,7 @@ const Header = () => {
|
||||
if (isFreePlan)
|
||||
setShowPricingModal()
|
||||
else
|
||||
setShowAccountSettingModal({ payload: 'billing' })
|
||||
setShowAccountSettingModal({ payload: ACCOUNT_SETTING_TAB.BILLING })
|
||||
}, [isFreePlan, setShowAccountSettingModal, setShowPricingModal])
|
||||
|
||||
if (isMobile) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { AppTypeIcon } from '@/app/components/app/type-selector'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { FileArrow01, FilePlus01, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
|
||||
import type { AppIconType, AppMode } from '@/types/app'
|
||||
import type { AppIconType, AppModeEnum } from '@/types/app'
|
||||
|
||||
export type NavItem = {
|
||||
id: string
|
||||
@@ -25,7 +25,7 @@ export type NavItem = {
|
||||
icon: string
|
||||
icon_background: string | null
|
||||
icon_url: string | null
|
||||
mode?: AppMode
|
||||
mode?: AppModeEnum
|
||||
}
|
||||
export type INavSelectorProps = {
|
||||
navigationItems: NavItem[]
|
||||
|
||||
Reference in New Issue
Block a user