Skip to content

Commit

Permalink
improve style
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Dec 25, 2024
1 parent 12c0edd commit 5257983
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 169 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import isEqual from 'fast-deep-equal';
import { useUserStore } from '@/store/user';
import { modelProviderSelectors } from '@/store/user/selectors';

import OptionRender from './ModelItem';
import ModelItem from '../ModelItem';

const EnabledModelList = ({ id, showAzureDeployName }) => {
const chatModelCards = useUserStore(modelProviderSelectors.getModelCardsById(id), isEqual);
Expand All @@ -20,12 +20,13 @@ const EnabledModelList = ({ id, showAzureDeployName }) => {
const label = displayName || id;

return (
<OptionRender
<ModelItem
displayName={label as string}
id={id as string}
isAzure={showAzureDeployName}
key={id}
provider={id}
sortable
// removed={enabledModels?.some((m) => id === m)}
/>
);
Expand Down
169 changes: 107 additions & 62 deletions src/app/(main)/settings/provider/components/ModelList/ModelItem.tsx
Original file line number Diff line number Diff line change
@@ -1,92 +1,137 @@
import { ModelIcon } from '@lobehub/icons';
import { ActionIcon, Tooltip } from '@lobehub/ui';
import { ActionIcon, Icon, Tag, Tooltip, copyToClipboard } from '@lobehub/ui';
import { Typography } from 'antd';
import { createStyles, useTheme } from 'antd-style';
import isEqual from 'fast-deep-equal';
import { LucideSettings, Recycle } from 'lucide-react';
import { GripVertical, LucideSettings, Recycle } from 'lucide-react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { ModelInfoTags } from '@/components/ModelSelect';
import { useUserStore } from '@/store/user';
import { modelProviderSelectors } from '@/store/user/selectors';
import { oneLineEllipsis } from '@/styles';

import CustomModelOption from './CustomModelOption';
export const useStyles = createStyles(({ css, token, cx }) => {
const grip = css`
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
color: ${token.colorTextSecondary};
transition: all 200ms ease-in-out;
opacity: 0;
`;

export const useStyles = createStyles(({ css, token }) => ({
container: css`
border-radius: ${token.borderRadius}px;
return {
container: css`
border-radius: 8px;
transition: all 0.2s ease-in-out;
transition: all 200ms ease-in-out;
&:hover {
color: inherit;
background-color: ${token.colorFillTertiary};
}
`,
}));
&:hover {
background-color: ${token.colorFillTertiary};
.${cx(grip)} {
opacity: 1;
}
}
position: relative;
`,
desc: css`
flex: 1;
min-width: 0;
span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
`,
grip,
};
});

interface OptionRenderProps {
displayName: string;
id: string;
isAzure?: boolean;
provider: string;
removed?: boolean;
sortable?: boolean;
}

const OptionRender = memo<OptionRenderProps>(({ displayName, id, provider, isAzure, removed }) => {
const { styles, cx } = useStyles();
const model = useUserStore((s) => modelProviderSelectors.getModelCardById(id)(s), isEqual);
const { t } = useTranslation(['components', 'setting']);
const theme = useTheme();
// if there is isCustom, it means it is a user defined custom model
if (model?.isCustom || isAzure) return <CustomModelOption id={id} provider={provider} />;
const OptionRender = memo<OptionRenderProps>(
({ displayName, id, provider, isAzure, removed, sortable }) => {
const { styles, cx } = useStyles();
const model = useUserStore((s) => modelProviderSelectors.getModelCardById(id)(s), isEqual);
const { t } = useTranslation(['components', 'setting', 'models']);
const theme = useTheme();
// // if there is isCustom, it means it is a user defined custom model
// if (model?.isCustom || isAzure) return <CustomModelOption id={id} provider={provider} />;

return (
<Flexbox
align={'center'}
className={styles.container}
gap={8}
horizontal
justify={'space-between'}
padding={'8px 16px'}
width={'100%'}
>
<Flexbox align={'center'} gap={8} horizontal>
<ModelIcon model={id} size={32} />
<Flexbox>
<Flexbox align={'center'} gap={8} horizontal>
{displayName}
return (
<Flexbox
align={'center'}
className={styles.container}
gap={24}
horizontal
justify={'space-between'}
padding={'8px 12px'}
width={'100%'}
>
<Flexbox align={'center'} flex={1} gap={8} horizontal style={{ minWidth: 0 }}>
{sortable && <Icon className={styles.grip} icon={GripVertical} size={{ fontSize: 12 }} />}
<ModelIcon model={id} size={32} />
<Flexbox flex={1} gap={4} style={{ minWidth: 0 }}>
<Flexbox align={'center'} gap={8} horizontal>
{displayName}
<Tag
onClick={() => {
copyToClipboard(id);
}}
style={{ cursor: 'pointer' }}
>
{id}
</Tag>
</Flexbox>
<div className={styles.desc}>
<Typography.Text
className={oneLineEllipsis}
ellipsis={{ tooltip: true }}
style={{ fontSize: 12, marginBottom: 0 }}
type={'secondary'}
>
{t(`${id}.description`, { defaultValue: id, ns: 'models' })}
</Typography.Text>
</div>
</Flexbox>
<Typography.Text style={{ fontSize: 12 }} type={'secondary'}>
{id}
</Typography.Text>
</Flexbox>
<Flexbox align={'center'} gap={8} horizontal>
<ModelInfoTags placement={'top'} {...model!} />
<ActionIcon
icon={LucideSettings}
onClick={async (e) => {
e.stopPropagation();
// toggleEditingCustomModelCard({ id, provider });
}}
title={t('llm.customModelCards.config', { ns: 'setting' })}
/>
{removed && (
<Tooltip
overlayStyle={{ maxWidth: 300 }}
placement={'top'}
style={{ pointerEvents: 'none' }}
title={t('ModelSelect.removed')}
>
<ActionIcon icon={Recycle} style={{ color: theme.colorWarning }} />
</Tooltip>
)}
</Flexbox>
</Flexbox>
<Flexbox align={'center'} gap={8} horizontal>
<ModelInfoTags placement={'top'} {...model!} />
<ActionIcon
icon={LucideSettings}
onClick={async (e) => {
e.stopPropagation();
// toggleEditingCustomModelCard({ id, provider });
}}
title={t('llm.customModelCards.config', { ns: 'setting' })}
/>
</Flexbox>
{removed && (
<Tooltip
overlayStyle={{ maxWidth: 300 }}
placement={'top'}
style={{ pointerEvents: 'none' }}
title={t('ModelSelect.removed')}
>
<ActionIcon icon={Recycle} style={{ color: theme.colorWarning }} />
</Tooltip>
)}
</Flexbox>
);
});
);
},
);

export default OptionRender;
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,11 @@ const ModelTitle = memo<ModelFetcherProps>(({ provider }) => {
align={'center'}
horizontal
justify={'space-between'}
paddingBlock={'4px 0'}
paddingBlock={8}
style={{ background: theme.colorBgLayout, position: 'sticky', top: -16, zIndex: 15 }}
>
{' '}
<Flexbox align={'center'} gap={0} horizontal justify={'space-between'}>
<Flexbox horizontal>
<Flexbox align={'center'} gap={8} horizontal>
<Typography.Text style={{ fontSize: 16, fontWeight: 'bold' }}>模型列表</Typography.Text>

<Typography.Text style={{ fontSize: 12 }} type={'secondary'}>
Expand All @@ -81,7 +80,7 @@ const ModelTitle = memo<ModelFetcherProps>(({ provider }) => {
title={
latestFetchTime
? t('llm.fetcher.latestTime', {
time: dayjs(latestFetchTime).format('YYYY-MM-DD HH:mm:ss'),
time: dayjs(latestFetchTime).format('YYYY-MM-DD HH:mm'),
})
: t('llm.fetcher.noLatestTime')
}
Expand Down Expand Up @@ -110,7 +109,7 @@ const ModelTitle = memo<ModelFetcherProps>(({ provider }) => {
>
{isValidating ? t('llm.fetcher.fetching') : t('llm.fetcher.fetch')}
</Button>
<Button size={'small'} icon={<Icon icon={PlusIcon} />}></Button>
<Button icon={<Icon icon={PlusIcon} />} size={'small'}></Button>
</Space.Compact>
</Flexbox>
</Flexbox>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client';

import { Typography } from 'antd';
import { useTheme } from 'antd-style';
import isEqual from 'fast-deep-equal';
import { ReactNode, memo } from 'react';
import { useTranslation } from 'react-i18next';
Expand Down Expand Up @@ -45,7 +44,7 @@ const ModelList = memo<ModelListProps>(({ showModelFetcher = false, id, showAzur
console.log(chatModelCards);
return (
<Flexbox gap={16}>
<ModelTitle showModelFetcher={showModelFetcher} provider={id} />
<ModelTitle provider={id} showModelFetcher={showModelFetcher} />
<ModelConfigModal provider={id} showAzureDeployName={showAzureDeployName} />

{!isUserStateInit ? (
Expand Down

0 comments on commit 5257983

Please sign in to comment.