diff --git a/CHANGELOG.md b/CHANGELOG.md
index e24b2b2bb8dcf..b2dfa36091280 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,31 @@
# Changelog
+### [Version 1.47.15](https://github.com/lobehub/lobe-chat/compare/v1.47.14...v1.47.15)
+
+Released on **2025-01-22**
+
+#### 💄 Styles
+
+- **misc**: Improve discover model page.
+
+
+
+
+Improvements and Fixes
+
+#### Styles
+
+- **misc**: Improve discover model page, closes [#5544](https://github.com/lobehub/lobe-chat/issues/5544) ([979849c](https://github.com/lobehub/lobe-chat/commit/979849c))
+
+
+
+
+
+[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
+
+
+
### [Version 1.47.14](https://github.com/lobehub/lobe-chat/compare/v1.47.13...v1.47.14)
Released on **2025-01-22**
diff --git a/changelog/v1.json b/changelog/v1.json
index e44f87f0a079f..49775ce05df38 100644
--- a/changelog/v1.json
+++ b/changelog/v1.json
@@ -1,4 +1,11 @@
[
+ {
+ "children": {
+ "improvements": ["Improve discover model page."]
+ },
+ "date": "2025-01-22",
+ "version": "1.47.15"
+ },
{
"children": {
"improvements": ["Support model list with model fetcher settings."]
diff --git a/package.json b/package.json
index f2f075f1b3daf..4c643bd0a89ff 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@lobehub/chat",
- "version": "1.47.14",
+ "version": "1.47.15",
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
"keywords": [
"framework",
diff --git a/src/app/(main)/discover/(detail)/model/[...slugs]/features/Header.tsx b/src/app/(main)/discover/(detail)/model/[...slugs]/features/Header.tsx
index 79b41a9860064..e5139112a30c0 100644
--- a/src/app/(main)/discover/(detail)/model/[...slugs]/features/Header.tsx
+++ b/src/app/(main)/discover/(detail)/model/[...slugs]/features/Header.tsx
@@ -3,6 +3,7 @@
import { ModelIcon } from '@lobehub/icons';
import { Button } from 'antd';
import { createStyles } from 'antd-style';
+import dayjs from 'dayjs';
import Link from 'next/link';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -20,7 +21,9 @@ export const useStyles = createStyles(({ css, token }) => ({
background: ${token.colorFillSecondary};
`,
time: css`
+ display: flex;
font-size: 12px;
+ line-height: 22px;
color: ${token.colorTextDescription};
`,
title: css`
@@ -41,6 +44,7 @@ const Header = memo(({ identifier, data, mobile }) => {
const { styles, theme } = useStyles();
const { t } = useTranslation(['discover', 'models']);
+ const releasedAt = data.meta.releasedAt;
return (
{!mobile && }
@@ -56,9 +60,11 @@ const Header = memo(({ identifier, data, mobile }) => {
style={{ color: theme.colorTextSecondary }}
>
{identifier}
-
+ {releasedAt && (
+
+ )}
diff --git a/src/app/(main)/discover/(detail)/model/[...slugs]/features/InfoSidebar/SuggestionItem.tsx b/src/app/(main)/discover/(detail)/model/[...slugs]/features/InfoSidebar/SuggestionItem.tsx
index 4023bf44510f1..d919f12e12fc7 100644
--- a/src/app/(main)/discover/(detail)/model/[...slugs]/features/InfoSidebar/SuggestionItem.tsx
+++ b/src/app/(main)/discover/(detail)/model/[...slugs]/features/InfoSidebar/SuggestionItem.tsx
@@ -44,13 +44,13 @@ export interface SuggestionItemProps
extends Omit,
FlexboxProps {}
-const SuggestionItem = memo(({ className, meta, identifier, ...rest }) => {
+const SuggestionItem = memo(({ className, meta, identifier }) => {
const { title, description, contextWindowTokens, vision, functionCall } = meta;
const { t } = useTranslation('models');
const { cx, styles } = useStyles();
return (
-
+
diff --git a/src/app/(main)/discover/(detail)/model/[...slugs]/features/ParameterList/index.tsx b/src/app/(main)/discover/(detail)/model/[...slugs]/features/ParameterList/index.tsx
index dc60078476461..4d11a87a6e7ae 100644
--- a/src/app/(main)/discover/(detail)/model/[...slugs]/features/ParameterList/index.tsx
+++ b/src/app/(main)/discover/(detail)/model/[...slugs]/features/ParameterList/index.tsx
@@ -89,10 +89,10 @@ const ParameterList = memo(({ data }) => {
item.key)}
- expandIconPosition={'right'}
+ expandIconPosition={'end'}
gap={16}
items={items.map((item) => ({
- children: ,
+ children: ,
key: item.key,
label: (
diff --git a/src/app/(main)/discover/(detail)/model/[...slugs]/features/ProviderList/index.tsx b/src/app/(main)/discover/(detail)/model/[...slugs]/features/ProviderList/index.tsx
index ef8d33ab64c35..d75440d621cd4 100644
--- a/src/app/(main)/discover/(detail)/model/[...slugs]/features/ProviderList/index.tsx
+++ b/src/app/(main)/discover/(detail)/model/[...slugs]/features/ProviderList/index.tsx
@@ -4,7 +4,7 @@ import { ModelIcon } from '@lobehub/icons';
import { Divider } from 'antd';
import { useTheme } from 'antd-style';
import { BrainCircuit } from 'lucide-react';
-import { memo } from 'react';
+import { Fragment, memo } from 'react';
import { useTranslation } from 'react-i18next';
import { DiscoverProviderItem } from '@/types/discover';
@@ -33,10 +33,10 @@ const ProviderList = memo(({ mobile, data, identifier }) => {
title={t('models.supportedProviders')}
>
{data.map((item, index) => (
- <>
-
- {index < data.length - 1 && }
- >
+
+
+ {index < data.length - 1 && }
+
))}
);
diff --git a/src/features/DevPanel/PostgresViewer/DataTable/Table.tsx b/src/features/DevPanel/PostgresViewer/DataTable/Table.tsx
index 19dc4fa1c16af..4c3e33cca3b49 100644
--- a/src/features/DevPanel/PostgresViewer/DataTable/Table.tsx
+++ b/src/features/DevPanel/PostgresViewer/DataTable/Table.tsx
@@ -2,13 +2,8 @@ import { createStyles } from 'antd-style';
import React from 'react';
import { Center } from 'react-layout-kit';
import { TableVirtuoso } from 'react-virtuoso';
-import useSWR from 'swr';
-import { tableViewerService } from '@/services/tableViewer';
-import { useGlobalStore } from '@/store/global';
-import { systemStatusSelectors } from '@/store/global/selectors';
-
-import { useTableColumns } from '../useTableColumns';
+import { usePgTable, useTableColumns } from '../usePgTable';
import TableCell from './TableCell';
const useStyles = createStyles(({ token, css }) => ({
@@ -100,12 +95,8 @@ const Table = ({ tableName }: TableProps) => {
const { styles } = useStyles();
const tableColumns = useTableColumns(tableName);
- const isDBInited = useGlobalStore(systemStatusSelectors.isDBInited);
- const tableData = useSWR(
- isDBInited && tableName ? ['fetch-table-data', tableName] : null,
- ([, table]) => tableViewerService.getTableData(table),
- );
+ const tableData = usePgTable(tableName);
const columns = tableColumns.data?.map((t) => t.name) || [];
const isLoading = tableColumns.isLoading || tableData.isLoading;
diff --git a/src/features/DevPanel/PostgresViewer/DataTable/index.tsx b/src/features/DevPanel/PostgresViewer/DataTable/index.tsx
index 8bb57920a8273..00bc5da814bb6 100644
--- a/src/features/DevPanel/PostgresViewer/DataTable/index.tsx
+++ b/src/features/DevPanel/PostgresViewer/DataTable/index.tsx
@@ -3,7 +3,9 @@ import { Button } from 'antd';
import { createStyles } from 'antd-style';
import { Download, Filter, RefreshCw } from 'lucide-react';
import React from 'react';
+import { mutate } from 'swr';
+import { FETCH_TABLE_DATA_KEY } from '../usePgTable';
import Table from './Table';
const useStyles = createStyles(({ token, css }) => ({
@@ -54,7 +56,13 @@ const DataTable = ({ tableName }: DataTableProps) => {
Filter
-
+ {
+ await mutate(FETCH_TABLE_DATA_KEY(tableName));
+ }}
+ title={'Refresh'}
+ />
diff --git a/src/features/DevPanel/PostgresViewer/Schema.tsx b/src/features/DevPanel/PostgresViewer/Schema.tsx
index 70353e29bd0e6..4d5438c3bde75 100644
--- a/src/features/DevPanel/PostgresViewer/Schema.tsx
+++ b/src/features/DevPanel/PostgresViewer/Schema.tsx
@@ -3,15 +3,10 @@ import { createStyles } from 'antd-style';
import { ChevronDown, ChevronRight, Database, Table as TableIcon } from 'lucide-react';
import React, { useState } from 'react';
import { Flexbox } from 'react-layout-kit';
-import useSWR from 'swr';
-
-import { tableViewerService } from '@/services/tableViewer';
-import { useGlobalStore } from '@/store/global';
-import { systemStatusSelectors } from '@/store/global/selectors';
import TableColumns from './TableColumns';
+import { useFetchTables } from './usePgTable';
-// 样式定义
const useStyles = createStyles(({ token, css }) => ({
button: css`
cursor: pointer;
@@ -138,11 +133,7 @@ const SchemaPanel = ({ onTableSelect, selectedTable }: SchemaPanelProps) => {
const { styles, cx } = useStyles();
const [expandedTables, setExpandedTables] = useState(new Set());
- const isDBInited = useGlobalStore(systemStatusSelectors.isDBInited);
-
- const { data, isLoading } = useSWR(isDBInited ? 'fetch-tables' : null, () =>
- tableViewerService.getAllTables(),
- );
+ const { data, isLoading } = useFetchTables();
const toggleTable = (tableName: string) => {
const newExpanded = new Set(expandedTables);
diff --git a/src/features/DevPanel/PostgresViewer/TableColumns.tsx b/src/features/DevPanel/PostgresViewer/TableColumns.tsx
index 3a4eaf69d9254..209b4f4bd6ddc 100644
--- a/src/features/DevPanel/PostgresViewer/TableColumns.tsx
+++ b/src/features/DevPanel/PostgresViewer/TableColumns.tsx
@@ -3,7 +3,7 @@ import { createStyles } from 'antd-style';
import React from 'react';
import { Flexbox } from 'react-layout-kit';
-import { useTableColumns } from './useTableColumns';
+import { useTableColumns } from './usePgTable';
const useStyles = createStyles(({ token, css }) => ({
container: css`
diff --git a/src/features/DevPanel/PostgresViewer/usePgTable.ts b/src/features/DevPanel/PostgresViewer/usePgTable.ts
new file mode 100644
index 0000000000000..5bb9472111fd7
--- /dev/null
+++ b/src/features/DevPanel/PostgresViewer/usePgTable.ts
@@ -0,0 +1,31 @@
+import useSWR from 'swr';
+
+import { tableViewerService } from '@/services/tableViewer';
+import { useGlobalStore } from '@/store/global';
+import { systemStatusSelectors } from '@/store/global/selectors';
+
+const FETCH_TABLES = 'fetch-tables';
+const FETCH_TABLE_COLUMN_KEY = (tableName: string) => ['fetch-table-columns', tableName];
+export const FETCH_TABLE_DATA_KEY = (tableName: string) => ['fetch-table-data', tableName];
+
+export const useFetchTables = () => {
+ const isDBInited = useGlobalStore(systemStatusSelectors.isDBInited);
+
+ return useSWR(isDBInited ? FETCH_TABLES : null, () => tableViewerService.getAllTables());
+};
+
+export const useTableColumns = (tableName?: string) => {
+ const isDBInited = useGlobalStore(systemStatusSelectors.isDBInited);
+
+ return useSWR(isDBInited && tableName ? FETCH_TABLE_COLUMN_KEY(tableName) : null, ([, table]) =>
+ tableViewerService.getTableDetails(table),
+ );
+};
+
+export const usePgTable = (tableName?: string) => {
+ const isDBInited = useGlobalStore(systemStatusSelectors.isDBInited);
+
+ return useSWR(isDBInited && tableName ? FETCH_TABLE_DATA_KEY(tableName) : null, ([, table]) =>
+ tableViewerService.getTableData(table),
+ );
+};
diff --git a/src/features/DevPanel/PostgresViewer/useTableColumns.ts b/src/features/DevPanel/PostgresViewer/useTableColumns.ts
deleted file mode 100644
index 13419cc35566d..0000000000000
--- a/src/features/DevPanel/PostgresViewer/useTableColumns.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import useSWR from 'swr';
-
-import { tableViewerService } from '@/services/tableViewer';
-import { useGlobalStore } from '@/store/global';
-import { systemStatusSelectors } from '@/store/global/selectors';
-
-export const useTableColumns = (tableName?: string) => {
- const isDBInited = useGlobalStore(systemStatusSelectors.isDBInited);
-
- return useSWR(isDBInited && tableName ? ['fetch-table-columns', tableName] : null, ([, table]) =>
- tableViewerService.getTableDetails(table),
- );
-};
diff --git a/src/services/config.ts b/src/services/config.ts
index 3473cba6312cf..81f416ae844ad 100644
--- a/src/services/config.ts
+++ b/src/services/config.ts
@@ -23,6 +23,9 @@ export interface ImportResults {
type?: string;
}
+/**
+ * @deprecated
+ */
class ConfigService {
importConfigState = async (config: ConfigFile, callbacks?: OnImportCallbacks): Promise => {
if (config.exportType === 'settings') {