feat: add baseSelect

This commit is contained in:
jialin
2025-09-17 19:53:40 +08:00
parent f36613227e
commit 1ac63e36df
12 changed files with 90 additions and 37 deletions
+4 -3
View File
@@ -6,8 +6,9 @@ import {
SyncOutlined SyncOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, Input, Select, Space } from 'antd'; import { Button, Input, Space } from 'antd';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import BaseSelect from '../seal-form/base/select';
import './index.less'; import './index.less';
type PageToolsProps = { type PageToolsProps = {
@@ -176,7 +177,7 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
onChange={handleInputChange} onChange={handleInputChange}
></Input> ></Input>
{showSelect && ( {showSelect && (
<Select <BaseSelect
allowClear allowClear
showSearch={false} showSearch={false}
placeholder={selectHolder} placeholder={selectHolder}
@@ -184,7 +185,7 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
size="large" size="large"
onChange={handleSelectChange} onChange={handleSelectChange}
options={selectOptions} options={selectOptions}
></Select> ></BaseSelect>
)} )}
<Button <Button
type="text" type="text"
+43
View File
@@ -0,0 +1,43 @@
import IconFont from '@/components/icon-font';
import type { SelectProps } from 'antd';
import { Select } from 'antd';
import React, { forwardRef, useImperativeHandle } from 'react';
const BaseSelect: React.FC<SelectProps> = forwardRef((props, ref) => {
const [isFocus, setIsFocus] = React.useState(false);
const inputRef = React.useRef<any>(null);
useImperativeHandle(ref, () => ({
...(inputRef.current || ({} as any))
}));
const handleFocus = (e: React.FocusEvent<HTMLDivElement>) => {
setIsFocus(true);
props.onFocus?.(e);
};
const handleBlur = (e: React.FocusEvent<HTMLDivElement>) => {
setIsFocus(false);
props.onBlur?.(e);
};
const renderSuffixIcon = () => {
if (props.suffixIcon) {
return props.suffixIcon;
}
if (!props.showSearch) {
return <IconFont type="icon-down"></IconFont>;
}
return !isFocus ? <IconFont type="icon-down"></IconFont> : undefined;
};
return (
<Select
{...props}
ref={inputRef}
onFocus={handleFocus}
onBlur={handleBlur}
suffixIcon={renderSuffixIcon()}
/>
);
});
export default BaseSelect;
+4 -3
View File
@@ -1,9 +1,10 @@
import { isNotEmptyValue } from '@/utils/index'; import { isNotEmptyValue } from '@/utils/index';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import type { SelectProps } from 'antd'; import type { SelectProps } from 'antd';
import { Form, Select } from 'antd'; import { Form } from 'antd';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, { useEffect, useMemo, useRef, useState } from 'react';
import BaseSelect from './base/select';
import { SealFormItemProps } from './types'; import { SealFormItemProps } from './types';
import Wrapper from './wrapper'; import Wrapper from './wrapper';
import SelectWrapper from './wrapper/select'; import SelectWrapper from './wrapper/select';
@@ -96,7 +97,7 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
disabled={props.disabled} disabled={props.disabled}
onClick={handleClickWrapper} onClick={handleClickWrapper}
> >
<Select <BaseSelect
{...rest} {...rest}
ref={inputRef} ref={inputRef}
options={children ? null : _options} options={children ? null : _options}
@@ -106,7 +107,7 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
notFoundContent={notFoundContent} notFoundContent={notFoundContent}
> >
{children} {children}
</Select> </BaseSelect>
</Wrapper> </Wrapper>
</SelectWrapper> </SelectWrapper>
); );
+4 -3
View File
@@ -1,10 +1,11 @@
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import type { SelectProps } from 'antd'; import type { SelectProps } from 'antd';
import { Checkbox, Select, Tag } from 'antd'; import { Checkbox, Tag } from 'antd';
import { CheckboxChangeEvent } from 'antd/es/checkbox'; import { CheckboxChangeEvent } from 'antd/es/checkbox';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import AutoTooltip from '../auto-tooltip'; import AutoTooltip from '../auto-tooltip';
import BaseSelect from './base/select';
const OptionWrapper = styled.div` const OptionWrapper = styled.div`
display: flex; display: flex;
@@ -236,7 +237,7 @@ const SimpleSelect: React.FC<SelectProps> = (props) => {
return ( return (
<div ref={selectRef}> <div ref={selectRef}>
<Select <BaseSelect
{...restProps} {...restProps}
options={optionsList} options={optionsList}
maxTagCount={0} maxTagCount={0}
@@ -251,7 +252,7 @@ const SimpleSelect: React.FC<SelectProps> = (props) => {
onSearch={handleOnSearch} onSearch={handleOnSearch}
filterOption={filterOption} filterOption={filterOption}
onOpenChange={handleOnOpenChange} onOpenChange={handleOnOpenChange}
></Select> ></BaseSelect>
</div> </div>
); );
}; };
+4 -3
View File
@@ -1,13 +1,14 @@
import { modelsExpandKeysAtom } from '@/atoms/models'; import { modelsExpandKeysAtom } from '@/atoms/models';
import MoreButton from '@/components/buttons/more'; import MoreButton from '@/components/buttons/more';
import PageTools from '@/components/page-tools'; import PageTools from '@/components/page-tools';
import BaseSelect from '@/components/seal-form/base/select';
import { PageAction } from '@/config'; import { PageAction } from '@/config';
import useBodyScroll from '@/hooks/use-body-scroll'; import useBodyScroll from '@/hooks/use-body-scroll';
import { IS_FIRST_LOGIN, writeState } from '@/utils/localstore/index'; import { IS_FIRST_LOGIN, writeState } from '@/utils/localstore/index';
import { SyncOutlined } from '@ant-design/icons'; import { SyncOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components'; import { PageContainer } from '@ant-design/pro-components';
import { useIntl, useNavigate } from '@umijs/max'; import { useIntl, useNavigate } from '@umijs/max';
import { Button, Input, Pagination, Select, Space, message } from 'antd'; import { Button, Input, Pagination, Space, message } from 'antd';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
import _ from 'lodash'; import _ from 'lodash';
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
@@ -278,7 +279,7 @@ const Catalog: React.FC = () => {
} }
onChange={handleNameChange} onChange={handleNameChange}
></Input> ></Input>
<Select <BaseSelect
allowClear allowClear
showSearch={false} showSearch={false}
placeholder={intl.formatMessage({ id: 'models.filter.category' })} placeholder={intl.formatMessage({ id: 'models.filter.category' })}
@@ -287,7 +288,7 @@ const Catalog: React.FC = () => {
maxTagCount={1} maxTagCount={1}
onChange={handleCategoryChange} onChange={handleCategoryChange}
options={categoryOptions} options={categoryOptions}
></Select> ></BaseSelect>
<Button <Button
type="text" type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }} style={{ color: 'var(--ant-color-text-tertiary)' }}
@@ -1,8 +1,9 @@
import { getRequestId } from '@/atoms/models'; import { getRequestId } from '@/atoms/models';
import BaseSelect from '@/components/seal-form/base/select';
import SimpleOverlay from '@/components/simple-overlay'; import SimpleOverlay from '@/components/simple-overlay';
import { createAxiosToken } from '@/hooks/use-chunk-request'; import { createAxiosToken } from '@/hooks/use-chunk-request';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Empty, Select, Spin } from 'antd'; import { Empty, Spin } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import React, { import React, {
forwardRef, forwardRef,
@@ -367,7 +368,7 @@ const HFModelFile: React.FC<HFModelFileProps> = forwardRef((props, ref) => {
{intl.formatMessage({ id: 'models.available.files' })} ( {intl.formatMessage({ id: 'models.available.files' })} (
{dataSource.fileList.length || 0}) {dataSource.fileList.length || 0})
</span> </span>
<Select <BaseSelect
value={sortType} value={sortType}
onChange={handleSortChange} onChange={handleSortChange}
labelRender={({ label }) => { labelRender={({ label }) => {
@@ -380,7 +381,7 @@ const HFModelFile: React.FC<HFModelFileProps> = forwardRef((props, ref) => {
options={modelFilesSortOptions.current} options={modelFilesSortOptions.current}
size="middle" size="middle"
style={{ width: '120px' }} style={{ width: '120px' }}
></Select> ></BaseSelect>
</TitleWrapper> </TitleWrapper>
{dataSource.loading && ( {dataSource.loading && (
<div className="spin-wrapper"> <div className="spin-wrapper">
@@ -1,8 +1,9 @@
import { getRequestId, setRquestId } from '@/atoms/models'; import { getRequestId, setRquestId } from '@/atoms/models';
import BaseSelect from '@/components/seal-form/base/select';
import { createAxiosToken } from '@/hooks/use-chunk-request'; import { createAxiosToken } from '@/hooks/use-chunk-request';
import { QuestionCircleOutlined } from '@ant-design/icons'; import { QuestionCircleOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Pagination, Select, Tooltip } from 'antd'; import { Pagination, Tooltip } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, { useEffect, useMemo, useRef, useState } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -547,7 +548,7 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
</div> </div>
<div className={SearchStyle.filter}> <div className={SearchStyle.filter}>
<span> <span>
<Select <BaseSelect
value={dataSource.sortType} value={dataSource.sortType}
onChange={handleSortChange} onChange={handleSortChange}
labelRender={({ label }) => { labelRender={({ label }) => {
@@ -560,7 +561,7 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
options={modelFilesSortOptions.current} options={modelFilesSortOptions.current}
size="middle" size="middle"
style={{ width: '150px' }} style={{ width: '150px' }}
></Select> ></BaseSelect>
{/* <Checkbox {/* <Checkbox
onChange={handleFilterGGUFChange} onChange={handleFilterGGUFChange}
className="m-l-8" className="m-l-8"
+6 -5
View File
@@ -4,6 +4,7 @@ import DropDownActions from '@/components/drop-down-actions';
import DropdownButtons from '@/components/drop-down-buttons'; import DropdownButtons from '@/components/drop-down-buttons';
import { PageSize } from '@/components/logs-viewer/config'; import { PageSize } from '@/components/logs-viewer/config';
import PageTools from '@/components/page-tools'; import PageTools from '@/components/page-tools';
import BaseSelect from '@/components/seal-form/base/select';
import SealTable from '@/components/seal-table'; import SealTable from '@/components/seal-table';
import { PageAction } from '@/config'; import { PageAction } from '@/config';
import useBodyScroll from '@/hooks/use-body-scroll'; import useBodyScroll from '@/hooks/use-body-scroll';
@@ -16,7 +17,7 @@ import { DownOutlined, SyncOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components'; import { PageContainer } from '@ant-design/pro-components';
import { useIntl, useNavigate } from '@umijs/max'; import { useIntl, useNavigate } from '@umijs/max';
import { useMemoizedFn } from 'ahooks'; import { useMemoizedFn } from 'ahooks';
import { Button, Input, Select, Space, message } from 'antd'; import { Button, Input, Space, message } from 'antd';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
import _ from 'lodash'; import _ from 'lodash';
import React, { import React, {
@@ -584,7 +585,7 @@ const Models: React.FC<ModelsProps> = ({
allowClear allowClear
onChange={handleNameChange} onChange={handleNameChange}
></Input> ></Input>
<Select <BaseSelect
allowClear allowClear
showSearch={false} showSearch={false}
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
@@ -595,8 +596,8 @@ const Models: React.FC<ModelsProps> = ({
maxTagCount={1} maxTagCount={1}
onChange={handleCategoryChange} onChange={handleCategoryChange}
options={modelCategories.filter((item) => item.value)} options={modelCategories.filter((item) => item.value)}
></Select> ></BaseSelect>
<Select <BaseSelect
allowClear allowClear
showSearch={false} showSearch={false}
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
@@ -607,7 +608,7 @@ const Models: React.FC<ModelsProps> = ({
maxTagCount={1} maxTagCount={1}
onChange={handleClusterChange} onChange={handleClusterChange}
options={clusterList} options={clusterList}
></Select> ></BaseSelect>
<Button <Button
type="text" type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }} style={{ color: 'var(--ant-color-text-tertiary)' }}
+4 -3
View File
@@ -1,12 +1,13 @@
import MoreButton from '@/components/buttons/more'; import MoreButton from '@/components/buttons/more';
import PageTools from '@/components/page-tools'; import PageTools from '@/components/page-tools';
import BaseSelect from '@/components/seal-form/base/select';
import CardList from '@/components/templates/card-list'; import CardList from '@/components/templates/card-list';
import CardSkeleton from '@/components/templates/card-skelton'; import CardSkeleton from '@/components/templates/card-skelton';
import useTableFetch from '@/hooks/use-table-fetch'; import useTableFetch from '@/hooks/use-table-fetch';
import { SyncOutlined } from '@ant-design/icons'; import { SyncOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components'; import { PageContainer } from '@ant-design/pro-components';
import { useIntl, useNavigate } from '@umijs/max'; import { useIntl, useNavigate } from '@umijs/max';
import { Button, Input, Select, Space } from 'antd'; import { Button, Input, Space } from 'antd';
import React from 'react'; import React from 'react';
import { MODELS_API, queryModelsList } from './apis'; import { MODELS_API, queryModelsList } from './apis';
import ModelItem from './components/model-item'; import ModelItem from './components/model-item';
@@ -96,7 +97,7 @@ const UserModels: React.FC = () => {
} }
onChange={handleNameChange} onChange={handleNameChange}
></Input> ></Input>
<Select <BaseSelect
allowClear allowClear
showSearch={false} showSearch={false}
placeholder={intl.formatMessage({ id: 'models.filter.category' })} placeholder={intl.formatMessage({ id: 'models.filter.category' })}
@@ -105,7 +106,7 @@ const UserModels: React.FC = () => {
maxTagCount={1} maxTagCount={1}
options={categoryOptions} options={categoryOptions}
onChange={handleCategoryChange} onChange={handleCategoryChange}
></Select> ></BaseSelect>
<Button <Button
type="text" type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }} style={{ color: 'var(--ant-color-text-tertiary)' }}
@@ -1,6 +1,7 @@
import AutoTooltip from '@/components/auto-tooltip'; import AutoTooltip from '@/components/auto-tooltip';
import IconFont from '@/components/icon-font'; import IconFont from '@/components/icon-font';
import OverlayScroller from '@/components/overlay-scroller'; import OverlayScroller from '@/components/overlay-scroller';
import BaseSelect from '@/components/seal-form/base/select';
import { import {
ClearOutlined, ClearOutlined,
DeleteOutlined, DeleteOutlined,
@@ -8,7 +9,7 @@ import {
SettingOutlined SettingOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, Checkbox, Dropdown, Popover, Select, Spin } from 'antd'; import { Button, Checkbox, Dropdown, Popover, Spin } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import 'overlayscrollbars/overlayscrollbars.css'; import 'overlayscrollbars/overlayscrollbars.css';
import React, { import React, {
@@ -239,7 +240,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
<div className="model-item"> <div className="model-item">
<div className="header"> <div className="header">
<span className="title"> <span className="title">
<Select <BaseSelect
style={{ width: '100%' }} style={{ width: '100%' }}
variant="borderless" variant="borderless"
options={modelFullList} options={modelFullList}
@@ -273,7 +274,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
</AutoTooltip> </AutoTooltip>
); );
}} }}
></Select> ></BaseSelect>
</span> </span>
{tokenResult && !loading && ( {tokenResult && !loading && (
<ReferenceParams usage={tokenResult} scaleable></ReferenceParams> <ReferenceParams usage={tokenResult} scaleable></ReferenceParams>
+5 -5
View File
@@ -1,8 +1,8 @@
import BaseSelect from '@/components/seal-form/base/select';
import useUserSettings from '@/hooks/use-user-settings'; import useUserSettings from '@/hooks/use-user-settings';
import langConfigMap from '@/locales/lang-config-map'; import langConfigMap from '@/locales/lang-config-map';
import { MoonOutlined, SunOutlined } from '@ant-design/icons'; import { MoonOutlined, SunOutlined } from '@ant-design/icons';
import { getAllLocales, setLocale, useIntl } from '@umijs/max'; import { getAllLocales, setLocale, useIntl } from '@umijs/max';
import { Select } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -70,25 +70,25 @@ const Appearance: React.FC = () => {
<span className="label"> <span className="label">
<span>{intl.formatMessage({ id: 'common.appearance.theme' })}</span> <span>{intl.formatMessage({ id: 'common.appearance.theme' })}</span>
</span> </span>
<Select <BaseSelect
value={userSettings.mode} value={userSettings.mode}
options={ThemeOptions} options={ThemeOptions}
onChange={handleOnChange} onChange={handleOnChange}
style={{ width: 200 }} style={{ width: 200 }}
></Select> ></BaseSelect>
</SettingsItem> </SettingsItem>
<SettingsItem> <SettingsItem>
<span className="label"> <span className="label">
<span>{intl.formatMessage({ id: 'common.settings.language' })}</span> <span>{intl.formatMessage({ id: 'common.settings.language' })}</span>
</span> </span>
<Select <BaseSelect
value={intl.locale} value={intl.locale}
options={languageOptions} options={languageOptions}
onChange={(value) => { onChange={(value) => {
setLocale(value, false); setLocale(value, false);
}} }}
style={{ width: 200 }} style={{ width: 200 }}
></Select> ></BaseSelect>
</SettingsItem> </SettingsItem>
</Wrapper> </Wrapper>
); );
@@ -1,7 +1,8 @@
import PageTools from '@/components/page-tools'; import PageTools from '@/components/page-tools';
import BaseSelect from '@/components/seal-form/base/select';
import { SyncOutlined } from '@ant-design/icons'; import { SyncOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, Input, Select, Space } from 'antd'; import { Button, Input, Space } from 'antd';
import { memo, useCallback, useEffect, useState } from 'react'; import { memo, useCallback, useEffect, useState } from 'react';
import { queryDashboardData } from '../apis'; import { queryDashboardData } from '../apis';
import DashboardContext from '../config/dashboard-context'; import DashboardContext from '../config/dashboard-context';
@@ -41,10 +42,10 @@ const Page: React.FC<{ setLoading: (loading: boolean) => void }> = ({
style={{ width: 200 }} style={{ width: 200 }}
allowClear allowClear
></Input> ></Input>
<Select <BaseSelect
style={{ width: 300 }} style={{ width: 300 }}
placeholder={intl.formatMessage({ id: 'usage.filter.model' })} placeholder={intl.formatMessage({ id: 'usage.filter.model' })}
></Select> ></BaseSelect>
<Button <Button
type="text" type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }} style={{ color: 'var(--ant-color-text-tertiary)' }}