feat(web): chat ui upgrade
This commit is contained in:
@@ -2,12 +2,13 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-06 21:11:51
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-17 18:39:09
|
||||
* @Last Modified time: 2026-03-20 14:25:26
|
||||
*/
|
||||
import { type FC, useRef, useState } from 'react'
|
||||
import RecordRTC from 'recordrtc'
|
||||
import { App } from 'antd'
|
||||
import { App, Tooltip } from 'antd'
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { fileUploadUrlWithoutApiPrefix } from '@/api/fileStorage'
|
||||
import { request } from '@/utils/request'
|
||||
@@ -91,14 +92,17 @@ const AudioRecorder: FC<AudioRecorderProps> = ({
|
||||
// Toggle between recording/idle states on click;
|
||||
// swap background image to reflect current state
|
||||
return (
|
||||
<div
|
||||
className={`rb:size-5.5 rb:bg-cover ${disabled ? 'rb:opacity-65 rb:cursor-not-allowed' : 'rb:cursor-pointer'} ${className} ${
|
||||
isRecording
|
||||
? `rb:bg-[url('@/assets/images/conversation/audio_ing.gif')]`
|
||||
: `rb:bg-[url('@/assets/images/conversation/audio.svg')]`
|
||||
}`}
|
||||
onClick={isRecording ? stopRecording : startRecording}
|
||||
/>
|
||||
<Tooltip title={isRecording ? t('memoryConversation.stopAudioRecorder') : t('memoryConversation.startAudioRecorder')}>
|
||||
<div
|
||||
className={clsx("rb:bg-cover", className, {
|
||||
'rb:cursor-pointer': !disabled,
|
||||
'rb:opacity-65 rb:cursor-not-allowed': disabled,
|
||||
"rb:size-4 rb:bg-[url('@/assets/images/conversation/audio.svg')]": !isRecording,
|
||||
"rb:size-6 rb:bg-[url('@/assets/images/conversation/audio_ing.gif')]": isRecording,
|
||||
})}
|
||||
onClick={isRecording ? stopRecording : startRecording}
|
||||
/>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2025-12-10 16:46:14
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-19 20:46:45
|
||||
* @Last Modified time: 2026-03-20 15:39:33
|
||||
*/
|
||||
import { type FC, useEffect, useMemo, useState } from 'react'
|
||||
import { Flex, Input, Form } from 'antd'
|
||||
@@ -77,85 +77,95 @@ const ChatInput: FC<ChatInputProps> = ({
|
||||
|
||||
return (
|
||||
<div className={`rb:absolute rb:bottom-3 rb:left-0 rb:right-0 rb:w-full ${className}`}>
|
||||
<Flex vertical justify="space-between" className={clsx("rb-border rb:shadow-[0px_2px_12px_0px_rgba(23,23,25,0.12)] rb:rounded-3xl rb:min-h-30", {
|
||||
<Flex gap={0} vertical justify="space-between" className={clsx("rb-border rb:shadow-[0px_2px_12px_0px_rgba(23,23,25,0.12)] rb:rounded-3xl rb:min-h-30", {
|
||||
' rb:border-[#171719]!': isFocus
|
||||
})}>
|
||||
{previewFileList.length > 0 && <div className="rb:overflow-x-auto rb:max-w-full"><Flex gap={14} className="rb:mx-3! rb:mt-3! rb:w-max!">
|
||||
{previewFileList.map((file) => {
|
||||
if (file.type.includes('image')) {
|
||||
{previewFileList.length > 0 && <div className="rb:overflow-x-auto rb:max-w-full">
|
||||
<Flex gap={14} className="rb:mx-3! rb:mt-3! rb:w-max! rb:mb-2!">
|
||||
{previewFileList.map((file) => {
|
||||
if (file.type.includes('image')) {
|
||||
return (
|
||||
<div key={file.url || file.uid} className="rb:inline-block rb:group rb:relative rb:rounded-lg rb:bg-[#F6F6F6] rb:border rb:border-[#F6F6F6]">
|
||||
<img src={file.url} alt={file.name} className="rb:size-12! rb:rounded-lg rb:object-cover" />
|
||||
<div
|
||||
className="rb:hidden rb:group-hover:block rb:absolute rb:-right-1 rb:-top-1 rb:size-3.5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/delete.svg')]"
|
||||
onClick={() => handleDelete(file)}
|
||||
></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (file.type.includes('video')) {
|
||||
return (
|
||||
<div key={file.url || file.uid} className="rb:w-45 rb:h-12 rb:inline-block rb:group rb:relative rb:rounded-lg rb:border rb:border-[#F6F6F6]">
|
||||
<video src={file.url} controls className="rb:w-45 rb:h-12 rb:rounded-lg rb:object-cover" />
|
||||
<div
|
||||
className="rb:hidden rb:group-hover:block rb:absolute rb:-right-1 rb:-top-1 rb:size-3.5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/delete.svg')]"
|
||||
onClick={() => handleDelete(file)}
|
||||
></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (file.type.includes('audio')) {
|
||||
return (
|
||||
<div key={file.url || file.uid} className="rb:w-45 rb:h-12 rb:inline-flex rb:items-center rb:group rb:relative rb:rounded-lg rb:bg-[#F6F6F6] rb:py-2 rb:px-2.5 rb:gap-2 rb:border rb:border-[#F6F6F6]">
|
||||
<audio src={file.url} controls className="rb:w-45 rb:h-12" />
|
||||
<div
|
||||
className="rb:hidden rb:group-hover:block rb:absolute rb:-right-1 rb:-top-1 rb:size-3.5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/delete.svg')]"
|
||||
onClick={() => handleDelete(file)}
|
||||
></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div key={file.url || file.uid} className="rb:inline-block rb:group rb:relative rb:rounded-lg">
|
||||
<img src={file.url} alt={file.name} className="rb:size-12! rb:rounded-lg rb:object-cover rb:cursor-pointer" />
|
||||
<Flex
|
||||
key={file.url || file.uid}
|
||||
align="center"
|
||||
gap={10}
|
||||
className="rb:w-45 rb:text-[12px] rb:group rb:relative rb:rounded-lg rb:bg-[#F6F6F6] rb:py-2! rb:px-2.5! rb:border rb:border-[#F6F6F6]"
|
||||
>
|
||||
<div
|
||||
className="rb:hidden rb:group-hover:block rb:absolute rb:-right-1 rb:-top-1 rb:size-3.5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/delete.svg')] rb:hover:bg-[url('@/assets/images/conversation/delete_hover.svg')]"
|
||||
className={clsx(
|
||||
"rb:size-5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/pdf_disabled.svg')]",
|
||||
file.type.includes('pdf')
|
||||
? "rb:bg-[url('src/assets/images/file/pdf.svg')]"
|
||||
: (file.type.includes('excel') || file.type.includes('spreadsheetml.sheet'))
|
||||
? "rb:bg-[url('src/assets/images/file/excel.svg')]"
|
||||
: file.type.includes('csv')
|
||||
? "rb:bg-[url('src/assets/images/file/csv.svg')]"
|
||||
: file.type.includes('html')
|
||||
? "rb:bg-[url('src/assets/images/file/html.svg')]"
|
||||
: file.type.includes('json')
|
||||
? "rb:bg-[url('src/assets/images/file/json.svg')]"
|
||||
: file.type.includes('ppt')
|
||||
? "rb:bg-[url('src/assets/images/file/ppt.svg')]"
|
||||
: file.type.includes('text')
|
||||
? "rb:bg-[url('src/assets/images/file/txt.svg')]"
|
||||
: file.type.includes('markdown')
|
||||
? "rb:bg-[url('src/assets/images/file/md.svg')]"
|
||||
: (file.type.includes('doc') || file.type.includes('docx') || file.type.includes('word') || file.type.includes('wordprocessingml.document'))
|
||||
? "rb:bg-[url('src/assets/images/file/word.svg')]"
|
||||
: null
|
||||
)}
|
||||
></div>
|
||||
<div className="rb:flex-1 rb:w-32.5">
|
||||
<div className="rb:leading-4 rb:text-ellipsis rb:overflow-hidden rb:whitespace-nowrap">{file.name}</div>
|
||||
<div className="rb:leading-3.5 rb:mt-0.5 rb:text-[#5B6167] rb:text-ellipsis rb:overflow-hidden rb:whitespace-nowrap">{file.type.split('/')[file.type.split('/').length - 1]} · {file.size}</div>
|
||||
</div>
|
||||
<div
|
||||
className="rb:hidden rb:group-hover:block rb:absolute rb:-right-1 rb:-top-1 rb:size-3.5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/delete.svg')]"
|
||||
onClick={() => handleDelete(file)}
|
||||
></div>
|
||||
</div>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
if (file.type.includes('video')) {
|
||||
return (
|
||||
<div key={file.url || file.uid} className="rb:w-45 rb:h-16 rb:inline-block rb:group rb:relative rb:rounded-lg">
|
||||
<video src={file.url} controls className="rb:w-45 rb:h-16 rb:rounded-lg rb:object-cover rb:cursor-pointer" />
|
||||
<div
|
||||
className="rb:hidden rb:group-hover:block rb:absolute rb:-right-1 rb:-top-1 rb:size-3.5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/delete.svg')] rb:hover:bg-[url('@/assets/images/conversation/delete_hover.svg')]"
|
||||
onClick={() => handleDelete(file)}
|
||||
></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (file.type.includes('audio')) {
|
||||
return (
|
||||
<div key={file.url || file.uid} className="rb:w-45 rb:h-16 rb:inline-flex rb:items-center rb:group rb:relative rb:rounded-lg rb:bg-[#F0F3F8] rb:py-2 rb:px-2.5 rb:gap-2">
|
||||
<audio src={file.url} controls className="rb:w-45 rb:h-16" />
|
||||
<div
|
||||
className="rb:hidden rb:group-hover:block rb:absolute rb:-right-1 rb:-top-1 rb:size-3.5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/delete.svg')] rb:hover:bg-[url('@/assets/images/conversation/delete_hover.svg')]"
|
||||
onClick={() => handleDelete(file)}
|
||||
></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Flex
|
||||
key={file.url || file.uid}
|
||||
align="center"
|
||||
gap={10}
|
||||
className="rb:w-45 rb:text-[12px] rb:group rb:relative rb:rounded-lg rb:bg-[#F0F3F8] rb:py-2! rb:px-2.5!"
|
||||
>
|
||||
{file.type.includes('pdf')
|
||||
? <div
|
||||
className="rb:size-5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/pdf_disabled.svg')] rb:hover:bg-[url('@/assets/images/conversation/pdf.svg')]"
|
||||
></div>
|
||||
: (file.type.includes('excel') || file.type.includes('spreadsheetml.sheet') || file.type.includes('csv'))
|
||||
? <div
|
||||
className="rb:size-5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/excel_disabled.svg')] rb:hover:bg-[url('@/assets/images/conversation/excel.svg')]"
|
||||
></div>
|
||||
: (file.type.includes('doc') || file.type.includes('docx') || file.type.includes('word') || file.type.includes('wordprocessingml.document'))
|
||||
? <div
|
||||
className="rb:size-5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/word_disabled.svg')] rb:hover:bg-[url('@/assets/images/conversation/word.svg')]"
|
||||
></div>
|
||||
: null
|
||||
}
|
||||
<div className="rb:flex-1 rb:w-32.5">
|
||||
<div className="rb:leading-4 rb:text-ellipsis rb:overflow-hidden rb:whitespace-nowrap">{file.name}</div>
|
||||
<div className="rb:leading-3.5 rb:mt-0.5 rb:text-[#5B6167] rb:text-ellipsis rb:overflow-hidden rb:whitespace-nowrap">{file.type} · {file.size}</div>
|
||||
</div>
|
||||
<div
|
||||
className="rb:hidden rb:group-hover:block rb:absolute rb:-right-1 rb:-top-1 rb:size-3.5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/delete.svg')] rb:hover:bg-[url('@/assets/images/conversation/delete_hover.svg')]"
|
||||
onClick={() => handleDelete(file)}
|
||||
></div>
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</Flex>
|
||||
})}
|
||||
</Flex>
|
||||
</div>}
|
||||
{/* Message input form */}
|
||||
<Form form={form} layout="vertical">
|
||||
<Form.Item name="message" noStyle>
|
||||
<Input.TextArea
|
||||
className="rb:m-[10px_12px_10px_12px]! rb:p-0! rb:w-[calc(100%-24px)]! rb:flex-[1_1_auto]"
|
||||
className="rb:m-[10px_12px_10px_12px]! rb:p-0! rb:w-[calc(100%-24px)]! rb:flex-[1_1_auto] rb:h-15! rb:resize-none! rb:rounded-none!"
|
||||
variant="borderless"
|
||||
autoSize={{ minRows: 2, maxRows: 2 }}
|
||||
onChange={(e) => onChange?.(e.target.value)}
|
||||
onKeyDown={(e) => {
|
||||
// Enter to send, Shift+Enter for new line
|
||||
@@ -171,17 +181,21 @@ const ChatInput: FC<ChatInputProps> = ({
|
||||
</Form>
|
||||
|
||||
{/* Bottom action area */}
|
||||
<Flex align="center" justify="space-between" className="rb:mx-2.5! rb:mt-0! rb:mb-2.5!">
|
||||
<Flex align="center" justify="space-between" gap={8} className="rb:mx-2.5! rb:mb-2.5!">
|
||||
{/* Child component content (such as buttons) */}
|
||||
<div className="rb:flex-1">{children}</div>
|
||||
<Flex align="center">
|
||||
{/* Send button - display different icons based on state */}
|
||||
{loading
|
||||
? <div className="rb:size-7 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/loading.svg')]"></div>
|
||||
: !values || !values?.message || values?.message?.trim() === ''
|
||||
? <div className="rb:size-7 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/sendDisabled.svg')]"></div>
|
||||
: <div className="rb:size-7 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/send.svg')]" onClick={handleSend}></div>
|
||||
}
|
||||
<Flex align="center" justify="center"
|
||||
className={clsx('rb:size-7 rb:rounded-full rb:shadow-[0px 2px 12px 0px rgba(23,23,25,0.1)]', {
|
||||
'rb:cursor-not-allowed rb:bg-[#F6F6F6]': loading || !values || !values?.message || values?.message?.trim() === '',
|
||||
'rb:cursor-pointer rb:bg-[#171719]': !loading && !(!values || !values?.message || values?.message?.trim() === '')
|
||||
})}
|
||||
onClick={handleSend}
|
||||
>
|
||||
<div className={clsx("rb:size-4 rb:bg-cover", {
|
||||
"rb:bg-[url('@/assets/images/conversation/loading.svg')]": loading,
|
||||
"rb:bg-[url('@/assets/images/conversation/sendDisabled.svg')]": !loading && (!values || !values?.message || values?.message?.trim() === ''),
|
||||
"rb:bg-[url('@/assets/images/conversation/send.svg')]": !loading && !(!values || !values?.message || values?.message?.trim() === '')
|
||||
})}></div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-03-17 14:22:25
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-18 15:55:13
|
||||
* @Last Modified time: 2026-03-20 15:44:48
|
||||
*/
|
||||
// Toolbar component for chat input area, supporting file upload, audio recording, and variable configuration
|
||||
import { useRef, forwardRef, useImperativeHandle, type ReactNode, useEffect } from 'react'
|
||||
import { Flex, Dropdown, Divider, App, Form, type MenuProps } from 'antd'
|
||||
import { SettingOutlined } from '@ant-design/icons'
|
||||
import { Flex, Dropdown, Divider, App, Form, type MenuProps, Tooltip } from 'antd'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import clsx from 'clsx'
|
||||
|
||||
@@ -31,7 +30,8 @@ export interface ChatToolbarRef {
|
||||
// Props for configuring toolbar features, upload settings, and event callbacks
|
||||
export interface ChatToolbarProps {
|
||||
features: FeaturesConfigForm
|
||||
extra?: ReactNode
|
||||
leftExtra?: ReactNode;
|
||||
rightExtra?: ReactNode
|
||||
uploadAction?: string
|
||||
uploadRequestConfig?: {
|
||||
data?: Record<string, string | number | boolean>
|
||||
@@ -51,7 +51,8 @@ interface FormValues {
|
||||
|
||||
const ChatToolbar = forwardRef<ChatToolbarRef, ChatToolbarProps>(({
|
||||
features,
|
||||
extra,
|
||||
leftExtra,
|
||||
rightExtra,
|
||||
uploadAction,
|
||||
uploadRequestConfig,
|
||||
onFilesChange,
|
||||
@@ -154,28 +155,34 @@ const ChatToolbar = forwardRef<ChatToolbarRef, ChatToolbarProps>(({
|
||||
return (
|
||||
<Form form={form} initialValues={{ files: [], variables: [] }}>
|
||||
<Flex justify="space-between" className="rb:flex-1">
|
||||
<Flex gap={8} align="center">
|
||||
<Flex gap={8} align="center" justify="start">
|
||||
<Form.Item name="files" noStyle hidden={!file_upload?.enabled || fileMenus.length === 0}>
|
||||
<Dropdown menu={{ items: fileMenus }}>
|
||||
<div className="rb:size-6 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/conversation/link.svg')] rb:hover:bg-[url('@/assets/images/conversation/link_hover.svg')]" />
|
||||
<Flex justify="center" align="center" className="rb:size-7 rb-border rb:cursor-pointer rb:hover:bg-[#F6F6F6] rb:rounded-full rb:shadow-[0px_2px_12px_0px_rgba(23,23,25,0.12)]">
|
||||
<div className="rb:size-4 rb:bg-cover rb:bg-[url('@/assets/images/conversation/link.svg')]" />
|
||||
</Flex>
|
||||
</Dropdown>
|
||||
</Form.Item>
|
||||
{extra}
|
||||
|
||||
{leftExtra}
|
||||
<Form.Item name="variables" className="rb:mb-0!" hidden={queryValues?.variables?.length < 1}>
|
||||
<div
|
||||
className={clsx('rb:flex rb:items-center rb:border rb:rounded-lg rb:px-2 rb:text-[12px] rb:h-6 rb:cursor-pointer rb:hover:bg-[#F0F3F8] rb:text-[#212332]', {
|
||||
'rb:border-[#FF5D34] rb:text-[#FF5D34]': isNeedVariableConfig,
|
||||
'rb:border-[#DFE4ED]': !isNeedVariableConfig,
|
||||
})}
|
||||
onClick={() => variableConfigModalRef.current?.handleOpen(queryValues.variables)}
|
||||
>
|
||||
<SettingOutlined className="rb:mr-1" />
|
||||
{t('memoryConversation.variableConfig')}
|
||||
</div>
|
||||
<Tooltip title={t('memoryConversation.variableConfig')}>
|
||||
<Flex justify="center" align="center"
|
||||
className={clsx("rb:size-7 rb:border rb:cursor-pointer rb:hover:bg-[#F6F6F6] rb:rounded-full rb:shadow-[0px_2px_12px_0px_rgba(23,23,25,0.12)]", {
|
||||
'rb:border-[#FF5D34]': isNeedVariableConfig,
|
||||
'rb:border-[#EBEBEB]': !isNeedVariableConfig,
|
||||
})}
|
||||
onClick={() => variableConfigModalRef.current?.handleOpen(queryValues.variables)}
|
||||
>
|
||||
<div className="rb:size-4 rb:bg-cover rb:bg-[url('@/assets/images/conversation/variables.svg')]" />
|
||||
</Flex>
|
||||
</Tooltip>
|
||||
</Form.Item>
|
||||
</Flex>
|
||||
{file_upload?.audio_enabled && file_upload?.allowed_transfer_methods?.includes('local_file') && (
|
||||
<Flex align="center">
|
||||
|
||||
<Flex align="center" justify="end" gap={8}>
|
||||
{rightExtra}
|
||||
{file_upload?.audio_enabled && file_upload?.allowed_transfer_methods?.includes('local_file') &&
|
||||
<AudioRecorder
|
||||
disabled={(queryValues?.files?.length || 0) >= file_upload.max_file_count}
|
||||
action={uploadAction}
|
||||
@@ -183,9 +190,9 @@ const ChatToolbar = forwardRef<ChatToolbarRef, ChatToolbarProps>(({
|
||||
onRecordingComplete={handleRecordingComplete}
|
||||
maxSize={file_upload?.audio_max_size_mb}
|
||||
/>
|
||||
<Divider type="vertical" className="rb:ml-1.5! rb:mr-3!" />
|
||||
</Flex>
|
||||
)}
|
||||
}
|
||||
{(rightExtra || (file_upload?.audio_enabled && file_upload?.allowed_transfer_methods?.includes('local_file'))) && <Divider type="vertical" className="rb:ml-1.5! rb:mr-0! rb:h-4!" />}
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<UploadFileListModal
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { CommunityD3Node, D3Link, HullDatum, CommunityGraphData, RawCommuni
|
||||
|
||||
// ─── Colors ───────────────────────────────────────────────────────────────────
|
||||
|
||||
export const GRAPH_COLORS = ['#155EEF', '#369F21', '#4DA8FF', '#FF5D34', '#9C6FFF', '#FF8A4C', '#8BAEF7', '#FFB048']
|
||||
export const GRAPH_COLORS = ['#171719', '#155EEF', '#369F21', '#4DA8FF', '#FF5D34', '#9C6FFF', '#FF8A4C', '#8BAEF7', '#FFB048']
|
||||
export const colorAt = (i: number) => GRAPH_COLORS[i % GRAPH_COLORS.length]
|
||||
|
||||
export function connectionToRadius(connections: number): number {
|
||||
@@ -336,7 +336,6 @@ export function initCommunityGraph(
|
||||
const svg = d3.select(container).append('svg')
|
||||
.attr('width', width).attr('height', height)
|
||||
.style('width', '100%').style('height', '100%')
|
||||
.style('background', '#F6F8FC')
|
||||
|
||||
const g = svg.append('g')
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.page-tabs:global(.ant-segmented) {
|
||||
background-color: rgba(91, 97, 103, 0.08);
|
||||
background-color: #F6F6F6;
|
||||
padding: 4px;
|
||||
}
|
||||
.page-tabs:global(.ant-segmented .ant-segmented-item-label) {
|
||||
|
||||
Reference in New Issue
Block a user