feat: add ThemeTag

This commit is contained in:
jialin
2025-04-28 10:05:06 +08:00
parent fb90d79eb3
commit 548e1378f5
8 changed files with 116 additions and 49 deletions
+28
View File
@@ -0,0 +1,28 @@
import useUserSettings from '@/hooks/use-user-settings';
import { Tag, TagProps } from 'antd';
import React from 'react';
const ThemeTag: React.FC<TagProps & { opacity?: number }> = ({
opacity,
style,
children,
...restProps
}) => {
const { userSettings } = useUserSettings();
const { isDarkTheme } = userSettings;
return (
<Tag
{...restProps}
style={{
...style,
opacity: isDarkTheme ? 1 : opacity
}}
>
{children}
</Tag>
);
};
ThemeTag.displayName = 'ThemeTag';
export default ThemeTag;
+19 -8
View File
@@ -2,8 +2,9 @@ import fallbackImg from '@/assets/images/img.png';
import AutoTooltip from '@/components/auto-tooltip';
import IconFont from '@/components/icon-font';
import TagWrapper from '@/components/tags-wrapper';
import ThemeTag from '@/components/tags-wrapper/theme-tag';
import { useIntl } from '@umijs/max';
import { Tag, Typography } from 'antd';
import { Typography } from 'antd';
import classNames from 'classnames';
import _ from 'lodash';
import React, { useCallback } from 'react';
@@ -31,9 +32,10 @@ const CatalogItem: React.FC<CatalogItemProps> = (props) => {
const renderTag = (sItem: any) => {
return (
<Tag
<ThemeTag
key={sItem}
className="tag-item"
opacity={0.7}
style={{
marginRight: 0,
display: 'flex',
@@ -42,12 +44,11 @@ const CatalogItem: React.FC<CatalogItemProps> = (props) => {
padding: '2px 6px',
borderRadius: 4,
fontSize: 12,
opacity: 0.7,
height: 22
}}
>
{sItem}B
</Tag>
</ThemeTag>
);
};
@@ -119,21 +120,31 @@ const CatalogItem: React.FC<CatalogItemProps> = (props) => {
<div className="tags">
{data.categories.map((sItem, i) => {
return (
<Tag key={sItem} className="tag-item" color="blue">
<ThemeTag
key={sItem}
className="tag-item"
color="blue"
opacity={0.7}
>
{_.find(modelCategories, { value: sItem })?.label || sItem}
</Tag>
</ThemeTag>
);
})}
{data.capabilities?.length > 0 &&
data.capabilities.map((sItem, i) => {
return (
<Tag key={sItem} className="tag-item" color="purple">
<ThemeTag
key={sItem}
className="tag-item"
color="purple"
opacity={0.7}
>
{_.map(_.split(sItem, '/'), (s: string) => {
return _.split(s, '_').join(' ');
})
.reverse()
.join(' ')}
</Tag>
</ThemeTag>
);
})}
{data.sizes?.length > 0 && (
@@ -5,6 +5,7 @@ import RowChildren from '@/components/seal-table/components/row-children';
import SimpleTabel, { ColumnProps } from '@/components/simple-table';
import InfoColumn from '@/components/simple-table/info-column';
import StatusTag from '@/components/status-tag';
import ThemeTag from '@/components/tags-wrapper/theme-tag';
import { HandlerOptions } from '@/hooks/use-chunk-fetch';
import useDownloadStream from '@/hooks/use-download-stream';
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
@@ -17,7 +18,7 @@ import {
ThunderboltFilled
} from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Col, Progress, Row, Tag, Tooltip, notification } from 'antd';
import { Button, Col, Progress, Row, Tooltip, notification } from 'antd';
import dayjs from 'dayjs';
import _ from 'lodash';
import React, { useCallback, useEffect, useMemo } from 'react';
@@ -480,7 +481,8 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
}}
title={renderDistributedServer(severList)}
>
<Tag
<ThemeTag
opacity={0.75}
color="processing"
style={{
marginRight: 0,
@@ -491,7 +493,6 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
opacity: 0.75,
borderRadius: 12
}}
>
@@ -499,7 +500,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
{intl.formatMessage({
id: 'models.table.acrossworker'
})}
</Tag>
</ThemeTag>
</Tooltip>
);
};
@@ -533,7 +534,8 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
<InfoColumn fieldList={fieldList} data={offloadData}></InfoColumn>
}
>
<Tag
<ThemeTag
opacity={0.75}
color="cyan"
style={{
display: 'flex',
@@ -543,7 +545,6 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
opacity: 0.75,
borderRadius: 12
}}
>
@@ -551,7 +552,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
{intl.formatMessage({
id: 'models.table.cpuoffload'
})}
</Tag>
</ThemeTag>
</Tooltip>
);
}, [
+18 -14
View File
@@ -1,6 +1,7 @@
import IconFont from '@/components/icon-font';
import MarkdownViewer from '@/components/markdown-viewer';
import SimpleOverlay from '@/components/simple-overlay';
import ThemeTag from '@/components/tags-wrapper/theme-tag';
import useRequestToken from '@/hooks/use-request-token';
import {
DownOutlined,
@@ -8,7 +9,7 @@ import {
RightOutlined
} from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Empty, Spin, Tag, Tooltip } from 'antd';
import { Button, Empty, Spin, Tooltip } from 'antd';
import { some } from 'lodash';
import 'overlayscrollbars/overlayscrollbars.css';
import React, {
@@ -317,26 +318,29 @@ const ModelCard: React.FC<{
<div className="model-card-wrap">
<div className="flex-center">
{modelType && (
<Tag className="tag-item" color="gold">
<span style={{ opacity: 0.65 }}>
<span className="m-r-5">
{intl.formatMessage({ id: 'models.architecture' })}:
</span>
{modelType}
<ThemeTag className="tag-item" color="gold" opacity={0.65}>
<span className="m-r-5">
{intl.formatMessage({ id: 'models.architecture' })}:
</span>
</Tag>
{modelType}
</ThemeTag>
)}
{isGGUFModel && (
<Tag className="tag-item" color="magenta">
<span style={{ opacity: 0.65 }}>GGUF</span>
</Tag>
<ThemeTag className="tag-item" color="magenta" opacity={0.65}>
GGUF
</ThemeTag>
)}
{!!modelTags.length &&
modelTags.map((tag: string, index: number) => {
return (
<Tag className="tag-item" color="geekblue" key={index}>
<span style={{ opacity: 0.65 }}>{tag}</span>
</Tag>
<ThemeTag
className="tag-item"
color="geekblue"
key={index}
opacity={0.65}
>
{tag}
</ThemeTag>
);
})}
</div>
@@ -1,8 +1,8 @@
import { TooltipOverlayScroller } from '@/components/overlay-scroller';
import ThemeTag from '@/components/tags-wrapper/theme-tag';
import { convertFileSize } from '@/utils';
import { InfoCircleOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Tag } from 'antd';
import classNames from 'classnames';
import _ from 'lodash';
import React from 'react';
@@ -29,7 +29,8 @@ const FilePartsTag = (props: { parts: any[] }) => {
return (
<TooltipOverlayScroller title={<FileParts fileList={parts}></FileParts>}>
<Tag
<ThemeTag
opacity={0.7}
className="tag-item"
color="purple"
style={{
@@ -43,7 +44,7 @@ const FilePartsTag = (props: { parts: any[] }) => {
{ n: parts.length }
)}
</span>
</Tag>
</ThemeTag>
</TooltipOverlayScroller>
);
};
@@ -65,7 +66,8 @@ const ModelFileItem: React.FC<ModelFileItemProps> = (props) => {
const quanType = getFileType(path);
if (quanType) {
return (
<Tag
<ThemeTag
opacity={0.7}
className="tag-item"
color="cyan"
style={{
@@ -73,7 +75,7 @@ const ModelFileItem: React.FC<ModelFileItemProps> = (props) => {
}}
>
{_.toUpper(quanType)}
</Tag>
</ThemeTag>
);
}
return null;
@@ -91,7 +93,8 @@ const ModelFileItem: React.FC<ModelFileItemProps> = (props) => {
<div className="title">{item.path}</div>
<div className="tags flex-between">
<span className="flex-center gap-8">
<Tag
<ThemeTag
opacity={0.7}
className="tag-item"
color="green"
style={{
@@ -99,7 +102,7 @@ const ModelFileItem: React.FC<ModelFileItemProps> = (props) => {
}}
>
{convertFileSize(item.size)}
</Tag>
</ThemeTag>
{getModelQuantizationType(item)}
<FilePartsTag parts={item.parts}></FilePartsTag>
</span>
@@ -37,7 +37,6 @@
border-radius: 4px;
font-size: 12px;
height: 22px;
opacity: 0.7;
}
.btn {
+1 -1
View File
@@ -4,7 +4,7 @@
width: max-content;
height: max-content;
padding: 32px;
background-color: rgba(255, 255, 255, 90%);
background-color: var(--ant-modal-content-bg);
:global(.field-wrapper) {
background-color: transparent !important;
+32 -11
View File
@@ -3,6 +3,7 @@ import { userAtom } from '@/atoms/user';
import Footer from '@/components/footer';
import useUserSettings from '@/hooks/use-user-settings';
import { useModel } from '@umijs/max';
import { ConfigProvider, theme } from 'antd';
import { useAtom } from 'jotai';
import { useEffect } from 'react';
import styled from 'styled-components';
@@ -37,7 +38,7 @@ const FormWrapper = styled.div`
width: max-content;
height: max-content;
padding: 32px;
background-color: rgba(255, 255, 255, 90%);
background-color: var(--ant-modal-content-bg);
.field-wrapper {
background-color: transparent !important;
@@ -49,10 +50,15 @@ const FormWrapper = styled.div`
`;
const Login = () => {
const { themeData } = useUserSettings();
const { themeData, userSettings } = useUserSettings();
const { token } = theme.useToken();
const [userInfo, setUserInfo] = useAtom(userAtom);
const { initialState, setInitialState } = useModel('@@initialState') || {};
const globalCssvars: Record<string, any> = {
'--ant-modal-content-bg': 'rgba(255, 255, 255, 0.9)'
};
const gotoDefaultPage = async (userInfo: any) => {
if (!userInfo || userInfo?.require_password_change) {
return;
@@ -74,15 +80,30 @@ const Login = () => {
}, []);
return (
<div>
<Wrapper></Wrapper>
<Box>
<FormWrapper>
{userInfo?.require_password_change ? <PasswordForm /> : <LoginForm />}
</FormWrapper>
<Footer />
</Box>
</div>
<ConfigProvider
componentSize="large"
key={userSettings.colorPrimary}
theme={{
algorithm: userSettings.isDarkTheme
? theme.darkAlgorithm
: theme.defaultAlgorithm,
...themeData
}}
>
<div style={globalCssvars}>
<Wrapper></Wrapper>
<Box>
<FormWrapper>
{userInfo?.require_password_change ? (
<PasswordForm />
) : (
<LoginForm />
)}
</FormWrapper>
<Footer />
</Box>
</div>
</ConfigProvider>
);
};