mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-02 19:00:49 +08:00
refactor: move modelsToEntries and entriesToModels to modelInputListUtils for better organization
This commit is contained in:
@@ -4,7 +4,8 @@ import { Button } from '@/components/ui/Button';
|
|||||||
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
import { ModelInputList } from '@/components/ui/ModelInputList';
|
||||||
|
import { modelsToEntries } from '@/components/ui/modelInputListUtils';
|
||||||
import type { ProviderKeyConfig } from '@/types';
|
import type { ProviderKeyConfig } from '@/types';
|
||||||
import { headersToEntries } from '@/utils/headers';
|
import { headersToEntries } from '@/utils/headers';
|
||||||
import { excludedModelsToText } from '../utils';
|
import { excludedModelsToText } from '../utils';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Input } from '@/components/ui/Input';
|
|||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import type { ProviderKeyConfig } from '@/types';
|
import type { ProviderKeyConfig } from '@/types';
|
||||||
import { headersToEntries } from '@/utils/headers';
|
import { headersToEntries } from '@/utils/headers';
|
||||||
import { modelsToEntries } from '@/components/ui/ModelInputList';
|
import { modelsToEntries } from '@/components/ui/modelInputListUtils';
|
||||||
import { excludedModelsToText } from '../utils';
|
import { excludedModelsToText } from '../utils';
|
||||||
import type { ProviderFormState, ProviderModalProps } from '../types';
|
import type { ProviderFormState, ProviderModalProps } from '../types';
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { Button } from '@/components/ui/Button';
|
|||||||
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
import { ModelInputList } from '@/components/ui/ModelInputList';
|
||||||
|
import { modelsToEntries } from '@/components/ui/modelInputListUtils';
|
||||||
import { useNotificationStore } from '@/stores';
|
import { useNotificationStore } from '@/stores';
|
||||||
import { apiCallApi, getApiCallErrorMessage } from '@/services/api';
|
import { apiCallApi, getApiCallErrorMessage } from '@/services/api';
|
||||||
import type { OpenAIProviderConfig, ApiKeyEntry } from '@/types';
|
import type { OpenAIProviderConfig, ApiKeyEntry } from '@/types';
|
||||||
|
|||||||
@@ -29,14 +29,8 @@ const PROVIDERS: ProviderNavItem[] = [
|
|||||||
export function ProviderNav() {
|
export function ProviderNav() {
|
||||||
const resolvedTheme = useThemeStore((state) => state.resolvedTheme);
|
const resolvedTheme = useThemeStore((state) => state.resolvedTheme);
|
||||||
const [activeProvider, setActiveProvider] = useState<ProviderId | null>(null);
|
const [activeProvider, setActiveProvider] = useState<ProviderId | null>(null);
|
||||||
const [mounted, setMounted] = useState(false);
|
|
||||||
const scrollContainerRef = useRef<HTMLElement | null>(null);
|
const scrollContainerRef = useRef<HTMLElement | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setMounted(true);
|
|
||||||
return () => setMounted(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const getScrollContainer = useCallback(() => {
|
const getScrollContainer = useCallback(() => {
|
||||||
if (scrollContainerRef.current) return scrollContainerRef.current;
|
if (scrollContainerRef.current) return scrollContainerRef.current;
|
||||||
const container = document.querySelector('.content') as HTMLElement | null;
|
const container = document.querySelector('.content') as HTMLElement | null;
|
||||||
@@ -74,7 +68,6 @@ export function ProviderNav() {
|
|||||||
const container = getScrollContainer();
|
const container = getScrollContainer();
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
handleScroll();
|
|
||||||
container.addEventListener('scroll', handleScroll, { passive: true });
|
container.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
return () => container.removeEventListener('scroll', handleScroll);
|
return () => container.removeEventListener('scroll', handleScroll);
|
||||||
}, [handleScroll, getScrollContainer]);
|
}, [handleScroll, getScrollContainer]);
|
||||||
@@ -120,7 +113,7 @@ export function ProviderNav() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!mounted) return null;
|
if (typeof document === 'undefined') return null;
|
||||||
|
|
||||||
return createPortal(navContent, document.body);
|
return createPortal(navContent, document.body);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { Button } from '@/components/ui/Button';
|
|||||||
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
import { ModelInputList } from '@/components/ui/ModelInputList';
|
||||||
|
import { modelsToEntries } from '@/components/ui/modelInputListUtils';
|
||||||
import type { ProviderKeyConfig } from '@/types';
|
import type { ProviderKeyConfig } from '@/types';
|
||||||
import { headersToEntries } from '@/utils/headers';
|
import { headersToEntries } from '@/utils/headers';
|
||||||
import type { ProviderModalProps, VertexFormState } from '../types';
|
import type { ProviderModalProps, VertexFormState } from '../types';
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
import { Button } from './Button';
|
import { Button } from './Button';
|
||||||
import { IconX } from './icons';
|
import { IconX } from './icons';
|
||||||
import type { ModelAlias } from '@/types';
|
import type { ModelEntry } from './modelInputListUtils';
|
||||||
|
|
||||||
interface ModelEntry {
|
|
||||||
name: string;
|
|
||||||
alias: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ModelInputListProps {
|
interface ModelInputListProps {
|
||||||
entries: ModelEntry[];
|
entries: ModelEntry[];
|
||||||
@@ -17,29 +12,6 @@ interface ModelInputListProps {
|
|||||||
aliasPlaceholder?: string;
|
aliasPlaceholder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const modelsToEntries = (models?: ModelAlias[]): ModelEntry[] => {
|
|
||||||
if (!Array.isArray(models) || models.length === 0) {
|
|
||||||
return [{ name: '', alias: '' }];
|
|
||||||
}
|
|
||||||
return models.map((m) => ({
|
|
||||||
name: m.name || '',
|
|
||||||
alias: m.alias || ''
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
export const entriesToModels = (entries: ModelEntry[]): ModelAlias[] => {
|
|
||||||
return entries
|
|
||||||
.filter((entry) => entry.name.trim())
|
|
||||||
.map((entry) => {
|
|
||||||
const model: ModelAlias = { name: entry.name.trim() };
|
|
||||||
const alias = entry.alias.trim();
|
|
||||||
if (alias && alias !== model.name) {
|
|
||||||
model.alias = alias;
|
|
||||||
}
|
|
||||||
return model;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export function ModelInputList({
|
export function ModelInputList({
|
||||||
entries,
|
entries,
|
||||||
onChange,
|
onChange,
|
||||||
|
|||||||
29
src/components/ui/modelInputListUtils.ts
Normal file
29
src/components/ui/modelInputListUtils.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import type { ModelAlias } from '@/types';
|
||||||
|
|
||||||
|
export interface ModelEntry {
|
||||||
|
name: string;
|
||||||
|
alias: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const modelsToEntries = (models?: ModelAlias[]): ModelEntry[] => {
|
||||||
|
if (!Array.isArray(models) || models.length === 0) {
|
||||||
|
return [{ name: '', alias: '' }];
|
||||||
|
}
|
||||||
|
return models.map((model) => ({
|
||||||
|
name: model.name || '',
|
||||||
|
alias: model.alias || ''
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const entriesToModels = (entries: ModelEntry[]): ModelAlias[] => {
|
||||||
|
return entries
|
||||||
|
.filter((entry) => entry.name.trim())
|
||||||
|
.map((entry) => {
|
||||||
|
const model: ModelAlias = { name: entry.name.trim() };
|
||||||
|
const alias = entry.alias.trim();
|
||||||
|
if (alias && alias !== model.name) {
|
||||||
|
model.alias = alias;
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -5,7 +5,8 @@ import { Card } from '@/components/ui/Card';
|
|||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
||||||
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
import { ModelInputList } from '@/components/ui/ModelInputList';
|
||||||
|
import { modelsToEntries } from '@/components/ui/modelInputListUtils';
|
||||||
import { useEdgeSwipeBack } from '@/hooks/useEdgeSwipeBack';
|
import { useEdgeSwipeBack } from '@/hooks/useEdgeSwipeBack';
|
||||||
import { SecondaryScreenShell } from '@/components/common/SecondaryScreenShell';
|
import { SecondaryScreenShell } from '@/components/common/SecondaryScreenShell';
|
||||||
import { providersApi } from '@/services/api';
|
import { providersApi } from '@/services/api';
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { providersApi } from '@/services/api';
|
|||||||
import { useAuthStore, useConfigStore, useNotificationStore } from '@/stores';
|
import { useAuthStore, useConfigStore, useNotificationStore } from '@/stores';
|
||||||
import type { ProviderKeyConfig } from '@/types';
|
import type { ProviderKeyConfig } from '@/types';
|
||||||
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
||||||
import { entriesToModels } from '@/components/ui/ModelInputList';
|
import { entriesToModels } from '@/components/ui/modelInputListUtils';
|
||||||
import { excludedModelsToText, parseExcludedModels } from '@/components/providers/utils';
|
import { excludedModelsToText, parseExcludedModels } from '@/components/providers/utils';
|
||||||
import type { ProviderFormState } from '@/components/providers';
|
import type { ProviderFormState } from '@/components/providers';
|
||||||
import layoutStyles from './AiProvidersEditLayout.module.scss';
|
import layoutStyles from './AiProvidersEditLayout.module.scss';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Outlet, useLocation, useNavigate, useParams } from 'react-router-dom';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { providersApi } from '@/services/api';
|
import { providersApi } from '@/services/api';
|
||||||
import { useAuthStore, useConfigStore, useNotificationStore } from '@/stores';
|
import { useAuthStore, useConfigStore, useNotificationStore } from '@/stores';
|
||||||
import { entriesToModels, modelsToEntries } from '@/components/ui/ModelInputList';
|
import { entriesToModels, modelsToEntries } from '@/components/ui/modelInputListUtils';
|
||||||
import type { ApiKeyEntry, OpenAIProviderConfig } from '@/types';
|
import type { ApiKeyEntry, OpenAIProviderConfig } from '@/types';
|
||||||
import type { ModelInfo } from '@/utils/models';
|
import type { ModelInfo } from '@/utils/models';
|
||||||
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import { Card } from '@/components/ui/Card';
|
|||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
||||||
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
import { ModelInputList } from '@/components/ui/ModelInputList';
|
||||||
|
import { modelsToEntries } from '@/components/ui/modelInputListUtils';
|
||||||
import { useEdgeSwipeBack } from '@/hooks/useEdgeSwipeBack';
|
import { useEdgeSwipeBack } from '@/hooks/useEdgeSwipeBack';
|
||||||
import { SecondaryScreenShell } from '@/components/common/SecondaryScreenShell';
|
import { SecondaryScreenShell } from '@/components/common/SecondaryScreenShell';
|
||||||
import { providersApi } from '@/services/api';
|
import { providersApi } from '@/services/api';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useRef, useState, type ChangeEvent } from 'react';
|
import { useCallback, useEffect, useRef, useState, type ChangeEvent } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Card } from '@/components/ui/Card';
|
import { Card } from '@/components/ui/Card';
|
||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
@@ -85,11 +85,16 @@ export function OAuthPage() {
|
|||||||
const timers = useRef<Record<string, number>>({});
|
const timers = useRef<Record<string, number>>({});
|
||||||
const vertexFileInputRef = useRef<HTMLInputElement | null>(null);
|
const vertexFileInputRef = useRef<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
|
const clearTimers = useCallback(() => {
|
||||||
|
Object.values(timers.current).forEach((timer) => window.clearInterval(timer));
|
||||||
|
timers.current = {};
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
Object.values(timers.current).forEach((timer) => window.clearInterval(timer));
|
clearTimers();
|
||||||
};
|
};
|
||||||
}, []);
|
}, [clearTimers]);
|
||||||
|
|
||||||
const updateProviderState = (provider: OAuthProvider, next: Partial<ProviderState>) => {
|
const updateProviderState = (provider: OAuthProvider, next: Partial<ProviderState>) => {
|
||||||
setStates((prev) => ({
|
setStates((prev) => ({
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export function SettingsPage() {
|
|||||||
setRoutingStrategy(config.routingStrategy);
|
setRoutingStrategy(config.routingStrategy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [config?.proxyUrl, config?.requestRetry, config?.logsMaxTotalSizeMb, config?.routingStrategy]);
|
}, [config]);
|
||||||
|
|
||||||
const setPendingFlag = (key: PendingKey, value: boolean) => {
|
const setPendingFlag = (key: PendingKey, value: boolean) => {
|
||||||
setPending((prev) => ({ ...prev, [key]: value }));
|
setPending((prev) => ({ ...prev, [key]: value }));
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export const useAuthStore = create<AuthStoreState>()(
|
|||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch {
|
||||||
set({
|
set({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
connectionStatus: 'error'
|
connectionStatus: 'error'
|
||||||
|
|||||||
Reference in New Issue
Block a user