chore(web): fix lint

This commit is contained in:
JzoNg
2026-04-03 15:13:52 +08:00
parent 756606f478
commit 231783eebe
17 changed files with 137 additions and 533 deletions

View File

@@ -97,7 +97,7 @@ const AppInfoDetailPanel = ({
<ContentDialog
show={show}
onClose={onClose}
className="absolute bottom-2 left-2 top-2 flex w-[420px] flex-col rounded-2xl p-0!"
className="absolute top-2 bottom-2 left-2 flex w-[420px] flex-col rounded-2xl p-0!"
>
<div className="flex shrink-0 flex-col items-start justify-center gap-3 self-stretch p-4">
<div className="flex items-center gap-3 self-stretch">
@@ -109,14 +109,14 @@ const AppInfoDetailPanel = ({
imageUrl={appDetail.icon_url}
/>
<div className="flex flex-1 flex-col items-start justify-center overflow-hidden">
<div className="w-full truncate text-text-secondary system-md-semibold">{appDetail.name}</div>
<div className="text-text-tertiary system-2xs-medium-uppercase">
<div className="w-full truncate system-md-semibold text-text-secondary">{appDetail.name}</div>
<div className="system-2xs-medium-uppercase text-text-tertiary">
{getAppModeLabel(appDetail.mode, t)}
</div>
</div>
</div>
{appDetail.description && (
<div className="overflow-wrap-anywhere max-h-[105px] w-full max-w-full overflow-y-auto whitespace-normal wrap-break-word text-text-tertiary system-xs-regular">
<div className="overflow-wrap-anywhere max-h-[105px] w-full max-w-full overflow-y-auto system-xs-regular wrap-break-word whitespace-normal text-text-tertiary">
{appDetail.description}
</div>
)}
@@ -142,7 +142,7 @@ const AppInfoDetailPanel = ({
onClick={switchOperation.onClick}
>
{switchOperation.icon}
<span className="text-text-tertiary system-sm-medium">{switchOperation.title}</span>
<span className="system-sm-medium text-text-tertiary">{switchOperation.title}</span>
</Button>
</div>
)}

View File

@@ -1,7 +1,7 @@
import type { ModelAndParameter } from '../configuration/debug/types'
import type { InputVar, Variable } from '@/app/components/workflow/types'
import type { I18nKeysByPrefix } from '@/types/i18n'
import type { PublishWorkflowParams } from '@/types/workflow'
import type { PublishWorkflowParams, WorkflowTypeConversionTarget } from '@/types/workflow'
import { useKeyPress } from 'ahooks'
import {
memo,
@@ -82,7 +82,7 @@ const AccessModeDisplay: React.FC<{ mode?: AccessMode }> = ({ mode }) => {
<>
<span className={`${icon} h-4 w-4 shrink-0 text-text-secondary`} />
<div className="grow truncate">
<span className="text-text-secondary system-sm-medium">{t(`accessControlDialog.accessItems.${label}`, { ns: 'app' })}</span>
<span className="system-sm-medium text-text-secondary">{t(`accessControlDialog.accessItems.${label}`, { ns: 'app' })}</span>
</div>
</>
)
@@ -270,7 +270,7 @@ const AppPublisher = ({
appId: appDetail.id,
},
query: {
target_type: workflowTypeSwitchConfig.targetType,
target_type: workflowTypeSwitchConfig.targetType as WorkflowTypeConversionTarget,
},
})
@@ -321,7 +321,7 @@ const AppPublisher = ({
<PortalToFollowElemTrigger onClick={handleTrigger}>
<Button
variant="primary"
className="py-2 pl-3 pr-2"
className="py-2 pr-2 pl-3"
disabled={disabled}
>
{t('common.publish', { ns: 'workflow' })}
@@ -331,13 +331,13 @@ const AppPublisher = ({
<PortalToFollowElemContent className="z-11">
<div className="w-[320px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5">
<div className="p-4 pt-3">
<div className="flex h-6 items-center text-text-tertiary system-xs-medium-uppercase">
<div className="flex h-6 items-center system-xs-medium-uppercase text-text-tertiary">
{publishedAt ? t('common.latestPublished', { ns: 'workflow' }) : t('common.currentDraftUnpublished', { ns: 'workflow' })}
</div>
{publishedAt
? (
<div className="flex items-center justify-between">
<div className="flex items-center text-text-secondary system-sm-medium">
<div className="flex items-center system-sm-medium text-text-secondary">
{t('common.publishedAt', { ns: 'workflow' })}
{' '}
{formatTimeFromNow(publishedAt)}
@@ -355,7 +355,7 @@ const AppPublisher = ({
</div>
)
: (
<div className="flex items-center text-text-secondary system-sm-medium">
<div className="flex items-center system-sm-medium text-text-secondary">
{t('common.autoSaved', { ns: 'workflow' })}
{' '}
·
@@ -392,7 +392,7 @@ const AppPublisher = ({
{workflowTypeSwitchConfig && (
<button
type="button"
className="flex h-8 w-full items-center justify-center gap-0.5 rounded-lg px-3 py-2 text-text-tertiary system-sm-medium hover:bg-state-base-hover disabled:cursor-not-allowed disabled:opacity-50"
className="flex h-8 w-full items-center justify-center gap-0.5 rounded-lg px-3 py-2 system-sm-medium text-text-tertiary hover:bg-state-base-hover disabled:cursor-not-allowed disabled:opacity-50"
onClick={handleWorkflowTypeSwitch}
disabled={publishDisabled || published || isConvertingWorkflowType}
>
@@ -431,7 +431,7 @@ const AppPublisher = ({
{showStartNodeLimitHint && (
<div className="mt-3 flex flex-col items-stretch">
<p
className="text-sm font-semibold leading-5 text-transparent"
className="text-sm leading-5 font-semibold text-transparent"
style={upgradeHighlightStyle}
>
<span className="block">{t('publishLimit.startNodeTitlePrefix', { ns: 'workflow' })}</span>
@@ -442,7 +442,7 @@ const AppPublisher = ({
</p>
<UpgradeBtn
isShort
className="mb-[12px] mt-[9px] h-[32px] w-[93px] self-start"
className="mt-[9px] mb-[12px] h-[32px] w-[93px] self-start"
/>
</div>
)}
@@ -457,10 +457,10 @@ const AppPublisher = ({
{systemFeatures.webapp_auth.enabled && (
<div className="p-4 pt-3">
<div className="flex h-6 items-center">
<p className="text-text-tertiary system-xs-medium">{t('publishApp.title', { ns: 'app' })}</p>
<p className="system-xs-medium text-text-tertiary">{t('publishApp.title', { ns: 'app' })}</p>
</div>
<div
className="flex h-8 cursor-pointer items-center gap-x-0.5 rounded-lg bg-components-input-bg-normal py-1 pl-2.5 pr-2 hover:bg-primary-50 hover:text-text-accent"
className="flex h-8 cursor-pointer items-center gap-x-0.5 rounded-lg bg-components-input-bg-normal py-1 pr-2 pl-2.5 hover:bg-primary-50 hover:text-text-accent"
onClick={() => {
setShowAppAccessControl(true)
}}
@@ -468,12 +468,12 @@ const AppPublisher = ({
<div className="flex grow items-center gap-x-1.5 overflow-hidden pr-1">
<AccessModeDisplay mode={appDetail?.access_mode} />
</div>
{!isAppAccessSet && <p className="shrink-0 text-text-tertiary system-xs-regular">{t('publishApp.notSet', { ns: 'app' })}</p>}
{!isAppAccessSet && <p className="shrink-0 system-xs-regular text-text-tertiary">{t('publishApp.notSet', { ns: 'app' })}</p>}
<div className="flex h-4 w-4 shrink-0 items-center justify-center">
<span className="i-ri-arrow-right-s-line h-4 w-4 text-text-quaternary" />
</div>
</div>
{!isAppAccessSet && <p className="mt-1 text-text-warning system-xs-regular">{t('publishApp.notSetDesc', { ns: 'app' })}</p>}
{!isAppAccessSet && <p className="mt-1 system-xs-regular text-text-warning">{t('publishApp.notSetDesc', { ns: 'app' })}</p>}
</div>
)}
{

View File

@@ -62,7 +62,7 @@ const TryLabel: FC<{
}> = ({ Icon, text, onClick }) => {
return (
<div
className="mr-1 mt-2 flex h-7 shrink-0 cursor-pointer items-center rounded-lg bg-components-button-secondary-bg px-2"
className="mt-2 mr-1 flex h-7 shrink-0 cursor-pointer items-center rounded-lg bg-components-button-secondary-bg px-2"
onClick={onClick}
>
<Icon className="h-4 w-4 text-text-tertiary"></Icon>
@@ -89,7 +89,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
const [model, setModel] = React.useState<Model>(localModel || {
name: '',
provider: '',
mode: mode as unknown as ModelModeType.chat,
mode: mode as unknown as ModelModeType,
completion_params: {} as CompletionParams,
})
const {
@@ -283,7 +283,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
<div className="flex h-[680px] flex-wrap">
<div className="h-full w-[570px] shrink-0 overflow-y-auto border-r border-divider-regular p-6">
<div className="mb-5">
<div className={`text-lg font-bold leading-[28px] ${s.textGradient}`}>{t('generate.title', { ns: 'appDebug' })}</div>
<div className={`text-lg leading-[28px] font-bold ${s.textGradient}`}>{t('generate.title', { ns: 'appDebug' })}</div>
<div className="mt-1 text-[13px] font-normal text-text-tertiary">{t('generate.description', { ns: 'appDebug' })}</div>
</div>
<div>
@@ -301,7 +301,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
{isBasicMode && (
<div className="mt-4">
<div className="flex items-center">
<div className="mr-3 shrink-0 text-xs font-semibold uppercase leading-[18px] text-text-tertiary">{t('generate.tryIt', { ns: 'appDebug' })}</div>
<div className="mr-3 shrink-0 text-xs leading-[18px] font-semibold text-text-tertiary uppercase">{t('generate.tryIt', { ns: 'appDebug' })}</div>
<div
className="h-px grow"
style={{
@@ -326,7 +326,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
{/* inputs */}
<div className="mt-4">
<div>
<div className="system-sm-semibold-uppercase mb-1.5 text-text-secondary">{t('generate.instruction', { ns: 'appDebug' })}</div>
<div className="mb-1.5 system-sm-semibold-uppercase text-text-secondary">{t('generate.instruction', { ns: 'appDebug' })}</div>
{isBasicMode
? (
<InstructionEditorInBasic

View File

@@ -70,7 +70,7 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = (
const [model, setModel] = React.useState<Model>(localModel || {
name: '',
provider: '',
mode: mode as unknown as ModelModeType.chat,
mode: mode as unknown as ModelModeType,
completion_params: defaultCompletionParams,
})
const {
@@ -202,7 +202,7 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = (
<div className="relative flex h-[680px] flex-wrap">
<div className="h-full w-[570px] shrink-0 overflow-y-auto border-r border-divider-regular p-6">
<div className="mb-5">
<div className={`text-lg font-bold leading-[28px] ${s.textGradient}`}>{t('codegen.title', { ns: 'appDebug' })}</div>
<div className={`text-lg leading-[28px] font-bold ${s.textGradient}`}>{t('codegen.title', { ns: 'appDebug' })}</div>
<div className="mt-1 text-[13px] font-normal text-text-tertiary">{t('codegen.description', { ns: 'appDebug' })}</div>
</div>
<div className="mb-4">
@@ -219,7 +219,7 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = (
</div>
<div>
<div className="text-[0px]">
<div className="mb-1.5 text-text-secondary system-sm-semibold-uppercase">{t('codegen.instruction', { ns: 'appDebug' })}</div>
<div className="mb-1.5 system-sm-semibold-uppercase text-text-secondary">{t('codegen.instruction', { ns: 'appDebug' })}</div>
<InstructionEditor
editorKey={editorKey}
value={instruction}

View File

@@ -1,8 +1,9 @@
import { parseAsStringLiteral } from 'nuqs'
import { AppModes } from '@/types/app'
export const APP_LIST_CATEGORY_VALUES = ['all', ...AppModes] as const
export type AppListCategory = typeof APP_LIST_CATEGORY_VALUES[number]
const APP_LIST_CATEGORY_VALUES = ['all', ...AppModes] as const
type AppListCategory = typeof APP_LIST_CATEGORY_VALUES[number]
export type { AppListCategory }
const appListCategorySet = new Set<string>(APP_LIST_CATEGORY_VALUES)

View File

@@ -1,5 +1,6 @@
'use client'
import type { AppListCategory } from './app-type-filter-shared'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import {
@@ -17,8 +18,8 @@ import { isAppListCategory } from './app-type-filter-shared'
const chipClassName = 'flex h-8 items-center gap-1 rounded-lg border-[0.5px] border-transparent bg-components-input-bg-normal px-2 text-[13px] leading-[18px] text-text-secondary hover:bg-components-input-bg-hover'
type AppTypeFilterProps = {
activeTab: import('./app-type-filter-shared').AppListCategory
onChange: (value: import('./app-type-filter-shared').AppListCategory) => void
activeTab: AppListCategory
onChange: (value: AppListCategory) => void
}
const AppTypeFilter = ({

View File

@@ -9,6 +9,8 @@ import { parsePlacement } from '@/app/components/base/ui/placement'
import { cn } from '@/utils/classnames'
export const Select = BaseSelect.Root
export const SelectGroup = BaseSelect.Group
export const SelectGroupLabel = BaseSelect.GroupLabel
export const SelectValue = BaseSelect.Value
const selectTriggerVariants = cva(
@@ -78,7 +80,7 @@ export function SelectTrigger({
role="button"
aria-label="Clear selection"
tabIndex={-1}
className="shrink-0 cursor-pointer text-text-quaternary hover:text-text-secondary group-data-disabled:hidden group-data-readonly:hidden"
className="shrink-0 cursor-pointer text-text-quaternary group-data-disabled:hidden group-data-readonly:hidden hover:text-text-secondary"
onClick={(e) => {
e.stopPropagation()
onClear?.()
@@ -91,7 +93,7 @@ export function SelectTrigger({
}
else {
trailingIcon = (
<BaseSelect.Icon className="shrink-0 text-text-quaternary transition-colors group-hover:text-text-secondary data-open:text-text-secondary group-data-readonly:hidden">
<BaseSelect.Icon className="shrink-0 text-text-quaternary transition-colors group-hover:text-text-secondary group-data-readonly:hidden data-open:text-text-secondary">
<span className="i-ri-arrow-down-s-line h-4 w-4" aria-hidden="true" />
</BaseSelect.Icon>
)
@@ -169,7 +171,7 @@ export function SelectContent({
<BaseSelect.Popup
className={cn(
'rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg',
'origin-(--transform-origin) transition-[transform,scale,opacity] data-ending-style:scale-95 data-starting-style:scale-95 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none',
'origin-(--transform-origin) transition-[transform,scale,opacity] data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0 motion-reduce:transition-none',
popupClassName,
)}
{...popupProps}
@@ -194,8 +196,8 @@ export function SelectItem({
return (
<BaseSelect.Item
className={cn(
'flex h-8 cursor-pointer items-center rounded-lg px-2 text-text-secondary outline-hidden system-sm-medium',
'data-disabled:cursor-not-allowed data-highlighted:bg-state-base-hover data-disabled:opacity-50',
'flex h-8 cursor-pointer items-center rounded-lg px-2 system-sm-medium text-text-secondary outline-hidden',
'data-disabled:cursor-not-allowed data-disabled:opacity-50 data-highlighted:bg-state-base-hover',
className,
)}
{...props}

View File

@@ -6,7 +6,7 @@ export const toEvaluationTargetType = (resourceType: 'workflow' | 'snippet'): Ev
return resourceType === 'snippet' ? 'snippets' : 'app'
}
export const humanizeMetricId = (metricId: string) => {
const humanizeMetricId = (metricId: string) => {
return metricId
.split(/[-_]/g)
.filter(Boolean)

View File

@@ -12,13 +12,13 @@ import type {
import type { NodeInfo } from '@/types/evaluation'
import { getComparisonOperators, getDefaultOperator, getEvaluationMockConfig } from './mock'
export type EvaluationStoreResources = Record<string, EvaluationResourceState>
type EvaluationStoreResources = Record<string, EvaluationResourceState>
const createId = (prefix: string) => `${prefix}-${Math.random().toString(36).slice(2, 10)}`
export const buildResourceKey = (resourceType: EvaluationResourceType, resourceId: string) => `${resourceType}:${resourceId}`
export const conditionOperatorsWithoutValue: ComparisonOperator[] = ['is_empty', 'is_not_empty']
const conditionOperatorsWithoutValue: ComparisonOperator[] = ['is_empty', 'is_not_empty']
export const requiresConditionValue = (operator: ComparisonOperator) => !conditionOperatorsWithoutValue.includes(operator)
@@ -100,7 +100,7 @@ export const buildInitialState = (resourceType: EvaluationResourceType): Evaluat
}
}
export const getResourceState = (
const getResourceState = (
resources: EvaluationStoreResources,
resourceType: EvaluationResourceType,
resourceId: string,

View File

@@ -21,7 +21,7 @@ export type CreateSnippetDialogPayload = {
graph: SnippetCanvasData
}
export type CreateSnippetDialogInitialValue = {
type CreateSnippetDialogInitialValue = {
name?: string
description?: string
icon?: AppIconSelection
@@ -111,8 +111,8 @@ const CreateSnippetDialog: FC<CreateSnippetDialogProps> = ({
<DialogContent className="w-[520px] max-w-[520px] p-0">
<DialogCloseButton />
<div className="px-6 pb-3 pt-6">
<DialogTitle className="text-text-primary title-2xl-semi-bold">
<div className="px-6 pt-6 pb-3">
<DialogTitle className="title-2xl-semi-bold text-text-primary">
{title || t('snippet.createDialogTitle', { ns: 'workflow' })}
</DialogTitle>
</div>
@@ -120,7 +120,7 @@ const CreateSnippetDialog: FC<CreateSnippetDialogProps> = ({
<div className="space-y-4 px-6 py-2">
<div className="flex items-end gap-3">
<div className="flex-1 pb-0.5">
<div className="mb-1 flex h-6 items-center text-text-secondary system-sm-medium">
<div className="mb-1 flex h-6 items-center system-sm-medium text-text-secondary">
{t('snippet.nameLabel', { ns: 'workflow' })}
</div>
<Input
@@ -144,7 +144,7 @@ const CreateSnippetDialog: FC<CreateSnippetDialogProps> = ({
</div>
<div>
<div className="mb-1 flex h-6 items-center text-text-secondary system-sm-medium">
<div className="mb-1 flex h-6 items-center system-sm-medium text-text-secondary">
{t('snippet.descriptionLabel', { ns: 'workflow' })}
</div>
<Textarea
@@ -157,7 +157,7 @@ const CreateSnippetDialog: FC<CreateSnippetDialogProps> = ({
</div>
</div>
<div className="flex items-center justify-end gap-2 px-6 pb-6 pt-5">
<div className="flex items-center justify-end gap-2 px-6 pt-5 pb-6">
<Button disabled={isSubmitting} onClick={handleClose}>
{t('operation.cancel', { ns: 'common' })}
</Button>
@@ -174,7 +174,7 @@ const CreateSnippetDialog: FC<CreateSnippetDialogProps> = ({
</DialogContent>
<DialogPortal>
<div className="pointer-events-none fixed left-1/2 top-1/2 z-[1002] flex -translate-x-1/2 translate-y-[170px] items-center gap-1 text-text-quaternary body-xs-regular">
<div className="pointer-events-none fixed top-1/2 left-1/2 z-[1002] flex -translate-x-1/2 translate-y-[170px] items-center gap-1 body-xs-regular text-text-quaternary">
<span>{t('snippet.shortcuts.press', { ns: 'workflow' })}</span>
<ShortcutsName keys={['ctrl', 'enter']} textColor="secondary" />
<span>{t('snippet.shortcuts.toConfirm', { ns: 'workflow' })}</span>

View File

@@ -76,10 +76,13 @@ describe('useConvertWorkflowTypeMutation', () => {
// Assert
await waitFor(() => {
expect(convertWorkflowTypeMutationFn).toHaveBeenCalledWith({
params: { appId: 'app-1' },
query: { target_type: 'evaluation' },
})
expect(convertWorkflowTypeMutationFn).toHaveBeenCalledWith(
{
params: { appId: 'app-1' },
query: { target_type: 'evaluation' },
},
expect.any(Object),
)
})
await waitFor(() => {
expect(invalidateQueries).toHaveBeenCalledWith({

View File

@@ -11,7 +11,6 @@ import type {
WorkflowDailyConversationsResponse,
} from '@/models/app'
import type { App } from '@/types/app'
import type { WorkflowTypeConversionTarget } from '@/types/workflow'
import {
keepPreviousData,
useInfiniteQuery,
@@ -171,8 +170,6 @@ export const useConvertWorkflowTypeMutation = () => {
})
}
export type { WorkflowTypeConversionTarget }
const useAppStatisticsQuery = <T>(metric: string, appId: string, params?: DateRangeParams) => {
return useQuery<T>({
queryKey: [NAME_SPACE, 'statistics', metric, appId, params],

View File

@@ -1,107 +1,6 @@
import type {
EvaluationConfigData,
EvaluationNodeInfoRequest,
EvaluationTargetType,
} from '@/types/evaluation'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useMutation, useQuery } from '@tanstack/react-query'
import { consoleQuery } from '@/service/client'
export type EvaluationResourceType = 'workflow' | 'pipeline' | 'snippet'
type EvaluationLogsParams = {
page?: number
page_size?: number
}
type EvaluationRunDetailParams = {
page?: number
page_size?: number
}
const toEvaluationTargetType = (resourceType: Exclude<EvaluationResourceType, 'pipeline'>): EvaluationTargetType => {
return resourceType === 'snippet' ? 'snippets' : 'app'
}
const invalidateEvaluationQueries = async (
queryClient: ReturnType<typeof useQueryClient>,
resourceType: EvaluationResourceType,
) => {
const queryKey = resourceType === 'pipeline'
? consoleQuery.datasetEvaluation.key()
: consoleQuery.evaluation.key()
await queryClient.invalidateQueries({ queryKey })
}
export const useEvaluationConfig = (resourceType: Exclude<EvaluationResourceType, 'pipeline'>, resourceId: string) => {
return useQuery(consoleQuery.evaluation.config.queryOptions({
input: {
params: {
targetType: toEvaluationTargetType(resourceType),
targetId: resourceId,
},
},
enabled: !!resourceId,
}))
}
export const useDatasetEvaluationConfig = (datasetId: string) => {
return useQuery(consoleQuery.datasetEvaluation.config.queryOptions({
input: {
params: { datasetId },
},
enabled: !!datasetId,
}))
}
export const useEvaluationLogs = (
resourceType: Exclude<EvaluationResourceType, 'pipeline'>,
resourceId: string,
params: EvaluationLogsParams = {},
) => {
return useQuery(consoleQuery.evaluation.logs.queryOptions({
input: {
params: {
targetType: toEvaluationTargetType(resourceType),
targetId: resourceId,
},
query: params,
},
enabled: !!resourceId,
}))
}
export const useDatasetEvaluationLogs = (datasetId: string, params: EvaluationLogsParams = {}) => {
return useQuery(consoleQuery.datasetEvaluation.logs.queryOptions({
input: {
params: { datasetId },
query: params,
},
enabled: !!datasetId,
}))
}
export const useEvaluationMetrics = (resourceType: Exclude<EvaluationResourceType, 'pipeline'>, resourceId: string) => {
return useQuery(consoleQuery.evaluation.metrics.queryOptions({
input: {
params: {
targetType: toEvaluationTargetType(resourceType),
targetId: resourceId,
},
},
enabled: !!resourceId,
}))
}
export const useDatasetEvaluationMetrics = (datasetId: string) => {
return useQuery(consoleQuery.datasetEvaluation.metrics.queryOptions({
input: {
params: { datasetId },
},
enabled: !!datasetId,
}))
}
export const useAvailableEvaluationMetrics = (enabled = true) => {
return useQuery(consoleQuery.evaluation.availableMetrics.queryOptions({
enabled,
@@ -111,112 +10,3 @@ export const useAvailableEvaluationMetrics = (enabled = true) => {
export const useEvaluationNodeInfoMutation = () => {
return useMutation(consoleQuery.evaluation.nodeInfo.mutationOptions())
}
export const useSaveEvaluationConfigMutation = (resourceType: Exclude<EvaluationResourceType, 'pipeline'>) => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.evaluation.saveConfig.mutationOptions({
onSuccess: async () => {
await invalidateEvaluationQueries(queryClient, resourceType)
},
}),
})
}
export const useSaveDatasetEvaluationConfigMutation = () => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.datasetEvaluation.saveConfig.mutationOptions({
onSuccess: async () => {
await invalidateEvaluationQueries(queryClient, 'pipeline')
},
}),
})
}
export const useStartEvaluationRunMutation = (resourceType: Exclude<EvaluationResourceType, 'pipeline'>) => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.evaluation.startRun.mutationOptions({
onSuccess: async () => {
await invalidateEvaluationQueries(queryClient, resourceType)
},
}),
})
}
export const useStartDatasetEvaluationRunMutation = () => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.datasetEvaluation.startRun.mutationOptions({
onSuccess: async () => {
await invalidateEvaluationQueries(queryClient, 'pipeline')
},
}),
})
}
export const useCancelEvaluationRunMutation = (resourceType: Exclude<EvaluationResourceType, 'pipeline'>) => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.evaluation.cancelRun.mutationOptions({
onSuccess: async () => {
await invalidateEvaluationQueries(queryClient, resourceType)
},
}),
})
}
export const useCancelDatasetEvaluationRunMutation = () => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.datasetEvaluation.cancelRun.mutationOptions({
onSuccess: async () => {
await invalidateEvaluationQueries(queryClient, 'pipeline')
},
}),
})
}
export const useEvaluationRunDetail = (
resourceType: Exclude<EvaluationResourceType, 'pipeline'>,
resourceId: string,
runId: string,
params: EvaluationRunDetailParams = {},
) => {
return useQuery(consoleQuery.evaluation.runDetail.queryOptions({
input: {
params: {
targetType: toEvaluationTargetType(resourceType),
targetId: resourceId,
runId,
},
query: params,
},
enabled: !!resourceId && !!runId,
}))
}
export const useDatasetEvaluationRunDetail = (datasetId: string, runId: string, params: EvaluationRunDetailParams = {}) => {
return useQuery(consoleQuery.datasetEvaluation.runDetail.queryOptions({
input: {
params: {
datasetId,
runId,
},
query: params,
},
enabled: !!datasetId && !!runId,
}))
}
export type {
EvaluationConfigData,
EvaluationNodeInfoRequest,
}

View File

@@ -2,11 +2,6 @@ import type { SnippetWorkflow } from '@/types/snippet'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { consoleQuery } from '@/service/client'
type WorkflowRunsParams = {
last_id?: string
limit?: number
}
const isNotFoundError = (error: unknown) => {
return !!error && typeof error === 'object' && 'status' in error && error.status === 404
}
@@ -68,15 +63,6 @@ export const useSnippetDraftWorkflow = (
})
}
export const useSnippetDraftConfig = (snippetId: string) => {
return useQuery(consoleQuery.snippets.draftConfig.queryOptions({
input: {
params: { snippetId },
},
enabled: !!snippetId,
}))
}
export const useSnippetPublishedWorkflow = (
snippetId: string,
onSuccess?: (publishedWorkflow: SnippetWorkflow) => void,
@@ -119,65 +105,6 @@ export const useSnippetDefaultBlockConfigs = (
})
}
export const useSnippetWorkflowRuns = (snippetId: string, params: WorkflowRunsParams = {}) => {
return useQuery(consoleQuery.snippets.workflowRuns.queryOptions({
input: {
params: { snippetId },
query: params,
},
enabled: !!snippetId,
}))
}
export const useSnippetWorkflowRunDetail = (snippetId: string, runId: string) => {
return useQuery(consoleQuery.snippets.workflowRunDetail.queryOptions({
input: {
params: {
snippetId,
runId,
},
},
enabled: !!snippetId && !!runId,
}))
}
export const useSnippetWorkflowRunNodeExecutions = (snippetId: string, runId: string) => {
return useQuery(consoleQuery.snippets.workflowRunNodeExecutions.queryOptions({
input: {
params: {
snippetId,
runId,
},
},
enabled: !!snippetId && !!runId,
}))
}
export const useSnippetDraftNodeLastRun = (snippetId: string, nodeId: string, enabled = true) => {
return useQuery(consoleQuery.snippets.lastDraftNodeRun.queryOptions({
input: {
params: {
snippetId,
nodeId,
},
},
enabled: !!snippetId && !!nodeId && enabled,
retry: 0,
}))
}
export const useSyncSnippetDraftWorkflowMutation = (snippetId: string) => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.snippets.syncDraftWorkflow.mutationOptions({
onSuccess: async () => {
await invalidateSnippetWorkflowQueries(queryClient, snippetId)
},
}),
})
}
export const usePublishSnippetWorkflowMutation = (snippetId: string) => {
const queryClient = useQueryClient()
@@ -189,31 +116,3 @@ export const usePublishSnippetWorkflowMutation = (snippetId: string) => {
}),
})
}
export const useRunSnippetDraftNodeMutation = () => {
return useMutation(consoleQuery.snippets.runDraftNode.mutationOptions())
}
export const useRunSnippetDraftIterationNodeMutation = () => {
return useMutation(consoleQuery.snippets.runDraftIterationNode.mutationOptions())
}
export const useRunSnippetDraftLoopNodeMutation = () => {
return useMutation(consoleQuery.snippets.runDraftLoopNode.mutationOptions())
}
export const useRunSnippetDraftWorkflowMutation = () => {
return useMutation(consoleQuery.snippets.runDraftWorkflow.mutationOptions())
}
export const useStopSnippetWorkflowTaskMutation = (snippetId: string) => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.snippets.stopWorkflowTask.mutationOptions({
onSuccess: async () => {
await invalidateSnippetWorkflowQueries(queryClient, snippetId)
},
}),
})
}

View File

@@ -1,6 +1,5 @@
import type { Node } from '@/app/components/workflow/types'
import type { SnippetDetailPayload, SnippetInputField, SnippetListItem } from '@/models/snippet'
import { useQuery } from '@tanstack/react-query'
import codeDefault from '@/app/components/workflow/nodes/code/default'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import httpDefault from '@/app/components/workflow/nodes/http/default'
@@ -11,9 +10,7 @@ import { BlockEnum, PromptRole } from '@/app/components/workflow/types'
import { PipelineInputVarType } from '@/models/pipeline'
import { AppModeEnum } from '@/types/app'
const NAME_SPACE = 'snippets'
export const getSnippetListMock = (): SnippetListItem[] => ([
const getSnippetListMock = (): SnippetListItem[] => ([
{
id: 'snippet-1',
name: 'Tone Rewriter',
@@ -206,23 +203,3 @@ export const getSnippetDetailMock = (snippetId: string): SnippetDetailPayload |
},
}
}
export const useSnippetDetail = (snippetId: string) => {
return useQuery({
queryKey: [NAME_SPACE, 'detail', snippetId],
queryFn: async () => getSnippetDetailMock(snippetId),
enabled: !!snippetId,
})
}
export const publishSnippet = async (_snippetId: string) => {
return Promise.resolve()
}
export const runSnippet = async (_snippetId: string) => {
return Promise.resolve()
}
export const updateSnippetInputFields = async (_snippetId: string, _fields: SnippetInputField[]) => {
return Promise.resolve()
}

View File

@@ -127,35 +127,8 @@ const normalizeSnippetListParams = (params: SnippetListParams) => {
}
}
const isNotFoundError = (error: unknown) => {
return !!error && typeof error === 'object' && 'status' in error && error.status === 404
}
const snippetListKey = (params: SnippetListParams) => ['snippets', 'list', params]
export const useSnippetList = (params: SnippetListParams = {}, options?: { enabled?: boolean }) => {
const query = normalizeSnippetListParams(params)
return useQuery(consoleQuery.snippets.list.queryOptions({
input: { query },
enabled: options?.enabled ?? true,
}))
}
export const useSnippetListItems = (params: SnippetListParams = {}, options?: { enabled?: boolean }) => {
return useQuery<SnippetListItemUIModel[]>({
queryKey: [...consoleQuery.snippets.list.queryKey({ input: { query: normalizeSnippetListParams(params) } }), 'items'],
queryFn: async () => {
const response = await consoleClient.snippets.list({
query: normalizeSnippetListParams(params),
})
return response.data.map(toSnippetListItem)
},
enabled: options?.enabled ?? true,
})
}
export const useInfiniteSnippetList = (params: SnippetListParams = {}, options?: { enabled?: boolean }) => {
const normalizedParams = normalizeSnippetListParams(params)
@@ -185,42 +158,6 @@ export const useSnippetApiDetail = (snippetId: string) => {
}))
}
export const useSnippetDetail = (snippetId: string) => {
return useQuery<SnippetDetailPayload | null>({
queryKey: [...consoleQuery.snippets.detail.queryKey({
input: {
params: { snippetId },
},
}), 'payload'],
enabled: !!snippetId,
queryFn: async () => {
try {
const [snippet, workflow] = await Promise.all([
consoleClient.snippets.detail({
params: { snippetId },
}),
consoleClient.snippets.draftWorkflow({
params: { snippetId },
}).catch((error) => {
if (isNotFoundError(error))
return undefined
throw error
}),
])
return buildSnippetDetailPayload(snippet, workflow)
}
catch (error) {
if (isNotFoundError(error))
return null
throw error
}
},
})
}
export const useCreateSnippetMutation = () => {
const queryClient = useQueryClient()
@@ -272,34 +209,6 @@ export const useExportSnippetMutation = () => {
})
}
export const usePublishSnippetMutation = () => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.snippets.publishWorkflow.mutationOptions({
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: consoleQuery.snippets.key(),
})
},
}),
})
}
export const useIncrementSnippetUseCountMutation = () => {
const queryClient = useQueryClient()
return useMutation({
...consoleQuery.snippets.incrementUseCount.mutationOptions({
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: consoleQuery.snippets.key(),
})
},
}),
})
}
export const useImportSnippetDSLMutation = () => {
const queryClient = useQueryClient()

View File

@@ -10,50 +10,71 @@ import type {
} from '@/models/datasets'
import type { AnnotationReplyConfig, ChatPromptConfig, CompletionPromptConfig, DatasetConfigs, PromptMode } from '@/models/debug'
export enum Theme {
light = 'light',
dark = 'dark',
system = 'system',
}
export type Theme = 'light' | 'dark' | 'system'
export const Theme = {
light: 'light' as Theme,
dark: 'dark' as Theme,
system: 'system' as Theme,
} as const
export enum ModelModeType {
chat = 'chat',
completion = 'completion',
unset = '',
}
export type ModelModeType = 'chat' | 'completion' | ''
export const ModelModeType = {
chat: 'chat' as ModelModeType,
completion: 'completion' as ModelModeType,
unset: '' as ModelModeType,
} as const
export enum RETRIEVE_TYPE {
oneWay = 'single',
multiWay = 'multiple',
}
export type RETRIEVE_TYPE = 'single' | 'multiple'
export const RETRIEVE_TYPE = {
oneWay: 'single' as RETRIEVE_TYPE,
multiWay: 'multiple' as RETRIEVE_TYPE,
} as const
export enum RETRIEVE_METHOD {
semantic = 'semantic_search',
fullText = 'full_text_search',
hybrid = 'hybrid_search',
invertedIndex = 'invertedIndex',
keywordSearch = 'keyword_search',
}
export type RETRIEVE_METHOD
= | 'semantic_search'
| 'full_text_search'
| 'hybrid_search'
| 'invertedIndex'
| 'keyword_search'
export const RETRIEVE_METHOD = {
semantic: 'semantic_search' as RETRIEVE_METHOD,
fullText: 'full_text_search' as RETRIEVE_METHOD,
hybrid: 'hybrid_search' as RETRIEVE_METHOD,
invertedIndex: 'invertedIndex' as RETRIEVE_METHOD,
keywordSearch: 'keyword_search' as RETRIEVE_METHOD,
} as const
/**
* App modes
*/
export enum AppModeEnum {
COMPLETION = 'completion',
WORKFLOW = 'workflow',
CHAT = 'chat',
ADVANCED_CHAT = 'advanced-chat',
AGENT_CHAT = 'agent-chat',
}
export type AppModeEnum
= | 'completion'
| 'workflow'
| 'chat'
| 'advanced-chat'
| 'agent-chat'
export const AppModeEnum = {
COMPLETION: 'completion' as AppModeEnum,
WORKFLOW: 'workflow' as AppModeEnum,
CHAT: 'chat' as AppModeEnum,
ADVANCED_CHAT: 'advanced-chat' as AppModeEnum,
AGENT_CHAT: 'agent-chat' as AppModeEnum,
} as const
export const AppModes = [AppModeEnum.COMPLETION, AppModeEnum.WORKFLOW, AppModeEnum.CHAT, AppModeEnum.ADVANCED_CHAT, AppModeEnum.AGENT_CHAT] as const
export enum AppTypeEnum {
WORKFLOW = 'workflow',
CHAT = 'chat',
RAG_PIPELINE = 'rag-pipeline',
SNIPPET = 'snippet',
EVALUATION = 'evaluation',
}
export type AppTypeEnum
= | 'workflow'
| 'chat'
| 'rag-pipeline'
| 'snippet'
| 'evaluation'
export const AppTypeEnum = {
WORKFLOW: 'workflow' as AppTypeEnum,
CHAT: 'chat' as AppTypeEnum,
RAG_PIPELINE: 'rag-pipeline' as AppTypeEnum,
SNIPPET: 'snippet' as AppTypeEnum,
EVALUATION: 'evaluation' as AppTypeEnum,
} as const
/**
* Variable type
@@ -131,10 +152,11 @@ export type ToolItem = {
}
} | AgentTool
export enum AgentStrategy {
functionCall = 'function_call',
react = 'react',
}
export type AgentStrategy = 'function_call' | 'react'
export const AgentStrategy = {
functionCall: 'function_call' as AgentStrategy,
react: 'react' as AgentStrategy,
} as const
export type CompletionParams = {
/** Maximum number of tokens in the answer message returned by Completion */
@@ -376,21 +398,24 @@ export type AppSSO = {
enable_sso: boolean
}
export enum Resolution {
low = 'low',
high = 'high',
}
export type Resolution = 'low' | 'high'
export const Resolution = {
low: 'low' as Resolution,
high: 'high' as Resolution,
} as const
export enum TransferMethod {
all = 'all',
local_file = 'local_file',
remote_url = 'remote_url',
}
export type TransferMethod = 'all' | 'local_file' | 'remote_url'
export const TransferMethod = {
all: 'all' as TransferMethod,
local_file: 'local_file' as TransferMethod,
remote_url: 'remote_url' as TransferMethod,
} as const
export enum TtsAutoPlay {
enabled = 'enabled',
disabled = 'disabled',
}
export type TtsAutoPlay = 'enabled' | 'disabled'
export const TtsAutoPlay = {
enabled: 'enabled' as TtsAutoPlay,
disabled: 'disabled' as TtsAutoPlay,
} as const
export const ALLOW_FILE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'webp', 'gif']