mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 18:08:07 +08:00
feat(model-provider): add plugin update indicators and migrate to oRPC contracts
Problem: Model provider settings page (/plugins?action=showSettings&tab=provider) was missing plugin update indicators (red dot badge, Update button) that the /plugins page correctly displayed, because it only fetched installation data without querying for latest marketplace versions. Decision: Extract a shared usePluginsWithLatestVersion hook and migrate plugin API endpoints to oRPC contracts, ensuring both pages use identical data flows. Model: Both pages now follow the same pattern — fetch installed plugins via consoleQuery.plugins.checkInstalled, enrich with latest version metadata via usePluginsWithLatestVersion, then pass complete PluginDetail objects downstream where useDetailHeaderState computes hasNewVersion for UI indicators. Impact: - Update badge red dot and Update button now appear on provider settings page - Shared hook eliminates 15 lines of duplicate enrichment logic in plugins-panel - oRPC contracts replace legacy post() calls for plugin endpoints - Operation dropdown uses auto-width to prevent "View on Marketplace" text wrapping - Version badge aligned to use Badge component consistently across both pages - Update button tooltip added with bilingual i18n support - Deprecated Tooltip migrated to Base UI Tooltip in detail-header
This commit is contained in:
@ -1,11 +1,14 @@
|
||||
import type { CategoryKey, TagKey } from './constants'
|
||||
import type { PluginDetail } from './types'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import {
|
||||
categoryKeys,
|
||||
tagKeys,
|
||||
} from './constants'
|
||||
import { PluginCategoryEnum } from './types'
|
||||
import { PluginCategoryEnum, PluginSource } from './types'
|
||||
|
||||
export type Tag = {
|
||||
name: TagKey
|
||||
@ -95,3 +98,39 @@ export const usePluginPageTabs = () => {
|
||||
]
|
||||
return tabs
|
||||
}
|
||||
|
||||
const EMPTY_PLUGINS: PluginDetail[] = []
|
||||
|
||||
export function usePluginsWithLatestVersion(plugins: PluginDetail[] = EMPTY_PLUGINS): PluginDetail[] {
|
||||
const marketplacePluginIds = useMemo(
|
||||
() => plugins
|
||||
.filter(p => p.source === PluginSource.marketplace)
|
||||
.map(p => p.plugin_id),
|
||||
[plugins],
|
||||
)
|
||||
|
||||
const { data: latestVersionData } = useQuery(consoleQuery.plugins.latestVersions.queryOptions({
|
||||
input: { body: { plugin_ids: marketplacePluginIds } },
|
||||
enabled: !!marketplacePluginIds.length,
|
||||
}))
|
||||
|
||||
return useMemo(() => {
|
||||
const versions = latestVersionData?.versions
|
||||
if (!versions)
|
||||
return plugins
|
||||
|
||||
return plugins.map((plugin) => {
|
||||
const info = versions[plugin.plugin_id]
|
||||
if (!info)
|
||||
return plugin
|
||||
return {
|
||||
...plugin,
|
||||
latest_version: info.version,
|
||||
latest_unique_identifier: info.unique_identifier,
|
||||
status: info.status,
|
||||
deprecated_reason: info.deprecated_reason,
|
||||
alternative_plugin_id: info.alternative_plugin_id,
|
||||
}
|
||||
})
|
||||
}, [plugins, latestVersionData])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user