Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(FR-534): introduce NEO style Tabs and RadioGroup #3139

Merged
merged 1 commit into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions react/src/components/AgentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import AgentSettingModal from './AgentSettingModal';
import BAIIntervalView from './BAIIntervalView';
import BAIProgressWithLabel from './BAIProgressWithLabel';
import BAIPropertyFilter from './BAIPropertyFilter';
import BAIRadioGroup from './BAIRadioGroup';
import DoubleTag from './DoubleTag';
import Flex from './Flex';
import { ResourceTypeIcon } from './ResourceNumber';
Expand All @@ -36,7 +37,6 @@ import {
import { useToggle } from 'ahooks';
import {
Button,
Segmented,
Table,
TableProps,
Tag,
Expand Down Expand Up @@ -778,7 +778,7 @@ const AgentList: React.FC<AgentListProps> = ({
style={{ flex: 1 }}
wrap="wrap"
>
<Segmented
<BAIRadioGroup
options={[
{
label: t('agent.Connected'),
Expand All @@ -792,7 +792,8 @@ const AgentList: React.FC<AgentListProps> = ({
value={
isPendingStatusFetch ? optimisticSelectedStatus : selectedStatus
}
onChange={(value) => {
onChange={(e) => {
const value = e.target.value;
setOptimisticSelectedStatus(value);
startStatusFetchTransition(() => {
setSelectedStatus(value);
Expand Down
16 changes: 5 additions & 11 deletions react/src/components/AgentSummaryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useResourceGroupsForCurrentProject } from '../hooks/useCurrentProject';
import { useHiddenColumnKeysSetting } from '../hooks/useHiddenColumnKeysSetting';
import BAIProgressWithLabel from './BAIProgressWithLabel';
import BAIPropertyFilter from './BAIPropertyFilter';
import BAIRadioGroup from './BAIRadioGroup';
import Flex from './Flex';
import { ResourceTypeIcon } from './ResourceNumber';
import TableColumnsSettingModal from './TableColumnsSettingModal';
Expand All @@ -26,15 +27,7 @@ import {
SettingOutlined,
} from '@ant-design/icons';
import { useToggle } from 'ahooks';
import {
Button,
Segmented,
Table,
TableProps,
theme,
Tooltip,
Typography,
} from 'antd';
import { Button, Table, TableProps, theme, Tooltip, Typography } from 'antd';
import { AnyObject } from 'antd/es/_util/type';
import { ColumnsType, ColumnType } from 'antd/es/table';
import graphql from 'babel-plugin-relay/macro';
Expand Down Expand Up @@ -374,7 +367,7 @@ const AgentSummaryList: React.FC<AgentSummaryListProps> = ({
style={{ flex: 1 }}
wrap="wrap"
>
<Segmented
<BAIRadioGroup
options={[
{
label: t('agent.Connected'),
Expand All @@ -388,7 +381,8 @@ const AgentSummaryList: React.FC<AgentSummaryListProps> = ({
value={
isPendingStatusFetch ? optimisticSelectedStatus : selectedStatus
}
onChange={(value) => {
onChange={(e) => {
const value = e.target.value;
setOptimisticSelectedStatus(value);
startStatusFetchTransition(() => {
setSelectedStatus(value);
Expand Down
16 changes: 16 additions & 0 deletions react/src/components/BAICard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React, { ReactNode } from 'react';
export interface BAICardProps extends CardProps {
status?: 'success' | 'error' | 'warning' | 'default';
extraButtonTitle?: string | ReactNode;
showDivider?: boolean;
onClickExtraButton?: () => void;
ref?: React.LegacyRef<HTMLDivElement> | undefined;
}
Expand All @@ -16,6 +17,8 @@ const BAICard: React.FC<BAICardProps> = ({
onClickExtraButton,
extra,
style,
styles,
showDivider,
...cardProps
}) => {
const { token } = theme.useToken();
Expand Down Expand Up @@ -50,6 +53,19 @@ const BAICard: React.FC<BAICardProps> = ({
? token.colorSuccess
: style?.borderColor, // default
})}
styles={_.merge(
showDivider
? {}
: {
header: {
borderBottom: 'none',
},
body: {
paddingTop: token.marginXS,
},
},
styles,
)}
extra={_extra}
{...cardProps}
/>
Expand Down
65 changes: 65 additions & 0 deletions react/src/components/BAIRadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { ConfigProvider, Radio, theme } from 'antd';
import type { RadioGroupProps } from 'antd';
import { createStyles } from 'antd-style';
import classNames from 'classnames';
import React from 'react';

interface BAIRadioGroupProps extends RadioGroupProps {}

const useStyle = createStyles(({ css, token }) => ({
baiRadioGroup: css`
// border version
.ant-radio-button-wrapper:not(.ant-radio-button-wrapper-checked)::before,
.ant-radio-button-wrapper:hover::before {
background-color: transparent;
}
.ant-radio-button-wrapper-checked:hover::before,
.ant-radio-button-wrapper-checked::before {
background-color: transparent;
/* background-color: ${`rgba(${parseInt(token.colorPrimary.slice(1, 3), 16)}, ${parseInt(token.colorPrimary.slice(3, 5), 16)}, ${parseInt(token.colorPrimary.slice(5, 7), 16)}, 0.30)`}; */
}

// original design version
/* .ant-radio-button-wrapper-checked::before,
.ant-radio-button-wrapper::before {
background-color: ${token.colorBorder};
}
.ant-radio-button-wrapper-checked:hover::before,
.ant-radio-button-wrapper:hover::before {
background-color: ${token.colorBorder};
}

.ant-radio-button-wrapper-checked {
border-color: transparent !important;
} */
`,
}));
const BAIRadioGroup: React.FC<BAIRadioGroupProps> = ({ options, ...props }) => {
const { styles } = useStyle();
const { token } = theme.useToken();
const colorPrimaryWithAlpha = `rgba(${parseInt(token.colorPrimary.slice(1, 3), 16)}, ${parseInt(token.colorPrimary.slice(3, 5), 16)}, ${parseInt(token.colorPrimary.slice(5, 7), 16)}, 0.15)`;
const colorPrimaryWithLessAlpha = `rgba(${parseInt(token.colorPrimary.slice(1, 3), 16)}, ${parseInt(token.colorPrimary.slice(3, 5), 16)}, ${parseInt(token.colorPrimary.slice(5, 7), 16)}, 0.3)`;
return (
<ConfigProvider
theme={{
components: {
Radio: {
buttonSolidCheckedBg: colorPrimaryWithAlpha,
buttonSolidCheckedColor: token.colorPrimary,
buttonSolidCheckedHoverBg: colorPrimaryWithLessAlpha,
},
},
}}
>
<Radio.Group
className={classNames(styles.baiRadioGroup, props.className)}
options={options}
optionType="button"
buttonStyle="solid"
{...props}
/>
</ConfigProvider>
);
};

export default BAIRadioGroup;
5 changes: 4 additions & 1 deletion react/src/components/BAITable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useThemeMode } from '../hooks/useThemeMode';
import { useDebounce } from 'ahooks';
import { ConfigProvider, GetProps, Table } from 'antd';
import { ConfigProvider, GetProps, Table, theme } from 'antd';
import { createStyles } from 'antd-style';
import { ColumnsType, ColumnType } from 'antd/es/table';
import { TableProps } from 'antd/lib';
Expand Down Expand Up @@ -124,6 +124,7 @@ const BAITable = <RecordType extends object = any>({
...tableProps
}: BAITableProps<RecordType>) => {
const { styles } = useStyles();
const { token } = theme.useToken();
const { isDarkMode } = useThemeMode();
const [resizedColumnWidths, setResizedColumnWidths] = useState<
Record<string, number>
Expand Down Expand Up @@ -163,6 +164,8 @@ const BAITable = <RecordType extends object = any>({
!isDarkMode && neoStyle
? {
headerBg: '#E3E3E3',
headerSplitColor: token.colorTextQuaternary,
// headerSplitColor: token.colorTextQuaternary
}
: undefined,
},
Expand Down
32 changes: 32 additions & 0 deletions react/src/components/BAITabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Tabs, TabsProps } from 'antd';
import { createStyles } from 'antd-style';
import classNames from 'classnames';
import React from 'react';

const useStyles = createStyles(({ token, css }) => ({
baiTabs: css`
.ant-tabs-nav::before {
border-color: ${token.colorPrimary};
}
.ant-tabs-tab:not(.ant-tabs-tab-active) {
border-bottom-color: ${token.colorPrimary};
}
.ant-tabs-tab.ant-tabs-tab-active {
border-color: ${token.colorPrimary};
}
`,
}));

interface BAITabsProps extends TabsProps {}
const BAITabs: React.FC<BAITabsProps> = ({ className, ...props }) => {
const { styles } = useStyles();
return (
<Tabs
className={classNames(styles.baiTabs, className)}
type="card"
{...props}
/>
);
};

export default BAITabs;
43 changes: 27 additions & 16 deletions react/src/components/ComputeSessionNodeItems/SessionStatusTag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
SessionStatusTagFragment$key,
} from './__generated__/SessionStatusTagFragment.graphql';
import { LoadingOutlined } from '@ant-design/icons';
import { Tag, theme } from 'antd';
import { Tag, theme, Tooltip } from 'antd';
import graphql from 'babel-plugin-relay/macro';
import _ from 'lodash';
import React from 'react';
Expand Down Expand Up @@ -69,24 +69,32 @@ const SessionStatusTag: React.FC<SessionStatusTagProps> = ({

return session ? (
_.isEmpty(session.status_info) || !showInfo ? (
<Tag
color={
session.status ? _.get(statusTagColor, session.status) : undefined
}
icon={isTransitional(session) ? <LoadingOutlined spin /> : undefined}
// Comment out to match the legacy tag style temporarily
// style={{
// borderRadius: 11,
// paddingLeft: token.paddingSM,
// paddingRight: token.paddingSM,
// }}
>
{session.status || ' '}
</Tag>
<Tooltip title={session.status_info}>
<Tag
color={
session.status ? _.get(statusTagColor, session.status) : undefined
}
icon={isTransitional(session) ? <LoadingOutlined spin /> : undefined}
// Comment out to match the legacy tag style temporarily
style={{
borderRadius: 11,
paddingLeft: token.paddingSM,
paddingRight: token.paddingSM,
}}
>
{session.status || ' '}
</Tag>
</Tooltip>
) : (
<Flex>
<Tag
style={{ margin: 0, zIndex: 1 }}
style={{
margin: 0,
zIndex: 1,
paddingLeft: token.paddingSM,
borderTopLeftRadius: 11,
borderBottomLeftRadius: 11,
}}
color={
session.status ? _.get(statusTagColor, session.status) : undefined
}
Expand All @@ -98,6 +106,9 @@ const SessionStatusTag: React.FC<SessionStatusTagProps> = ({
margin: 0,
marginLeft: -1,
borderStyle: 'dashed',
paddingRight: token.paddingSM,
borderTopRightRadius: 11,
borderBottomRightRadius: 11,
color:
session.status_info &&
_.get(statusInfoTagColor, session.status_info)
Expand Down
Loading