mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-20 06:34:55 +00:00
[improvement][semantic-fe] Upgrading antd version to 5.x, extracting the batch operation button component, optimizing the interaction for system settings, and expanding the configuration generation types for list-to-select component. (#404)
* [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab. [improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions. [improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager. * [improvement][semantic-fe] Add time granularity setting in the data source configuration. * [improvement][semantic-fe] Dictionary import for dimension values supported in Q&A visibility * [improvement][semantic-fe] Modification of data source creation prompt wording" * [improvement][semantic-fe] metric market experience optimization * [improvement][semantic-fe] enhance the analysis of metric trends * [improvement][semantic-fe] optimize the presentation of metric trend permissions * [improvement][semantic-fe] add metric trend download functionality * [improvement][semantic-fe] fix the dimension initialization issue in metric correlation * [improvement][semantic-fe] Fix the issue of database changes not taking effect when creating based on an SQL data source. * [improvement][semantic-fe] Optimizing pagination logic and some CSS styles * [improvement][semantic-fe] Fixing the API for the indicator list by changing "current" to "pageNum" * [improvement][semantic-fe] Fixing the default value setting for the indicator list * [improvement][semantic-fe] Adding batch operations for indicators/dimensions/models * [improvement][semantic-fe] Replacing the single status update API for indicators/dimensions with a batch update API * [improvement][semantic-fe] Redesigning the indicator homepage to incorporate trend charts and table functionality for indicators * [improvement][semantic-fe] Optimizing the logic for setting dimension values and editing data sources, and adding system settings functionality * [improvement][semantic-fe] Upgrading antd version to 5.x, extracting the batch operation button component, optimizing the interaction for system settings, and expanding the configuration generation types for list-to-select component.
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
import { Space, Popconfirm, Dropdown, DatePicker, Popover, Button, Radio } from 'antd';
|
||||
import { FC, useState, useRef } from 'react';
|
||||
import {
|
||||
PlaySquareOutlined,
|
||||
StopOutlined,
|
||||
CloudDownloadOutlined,
|
||||
DeleteOutlined,
|
||||
} from '@ant-design/icons';
|
||||
|
||||
export type BatchCtrlDropDownButtonProps = {
|
||||
onMenuClick?: (key: string) => void;
|
||||
onDownloadDateRangeChange?: (dateRange: string[], pickerType: string) => void;
|
||||
onDeleteConfirm?: () => void;
|
||||
downloadLoading?: boolean;
|
||||
disabledList?: string[];
|
||||
hiddenList?: string[];
|
||||
};
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const BatchCtrlDropDownButton: FC<BatchCtrlDropDownButtonProps> = ({
|
||||
onMenuClick,
|
||||
onDownloadDateRangeChange,
|
||||
onDeleteConfirm,
|
||||
downloadLoading,
|
||||
disabledList = [],
|
||||
hiddenList = [],
|
||||
}) => {
|
||||
const [popoverOpenState, setPopoverOpenState] = useState<boolean>(false);
|
||||
const [pickerType, setPickerType] = useState<string>('day');
|
||||
const dateRangeRef = useRef<any>([]);
|
||||
const dropdownButtonItems: any[] = [
|
||||
{
|
||||
key: 'batchStart',
|
||||
label: '批量启用',
|
||||
icon: <PlaySquareOutlined />,
|
||||
disabled: disabledList?.includes('batchStart'),
|
||||
},
|
||||
{
|
||||
key: 'batchStop',
|
||||
label: '批量停用',
|
||||
icon: <StopOutlined />,
|
||||
disabled: disabledList?.includes('batchStop'),
|
||||
},
|
||||
{
|
||||
key: 'batchDownload',
|
||||
label: (
|
||||
<a
|
||||
onClick={() => {
|
||||
setPopoverOpenState(true);
|
||||
}}
|
||||
>
|
||||
批量下载
|
||||
</a>
|
||||
),
|
||||
icon: <CloudDownloadOutlined />,
|
||||
disabled: disabledList?.includes('batchDownload'),
|
||||
},
|
||||
{
|
||||
key: 'batchDeleteDivider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
key: 'batchDelete',
|
||||
label: (
|
||||
<Popconfirm
|
||||
title="确定批量删除吗?"
|
||||
onConfirm={() => {
|
||||
onDeleteConfirm?.();
|
||||
}}
|
||||
>
|
||||
<a>批量删除</a>
|
||||
</Popconfirm>
|
||||
),
|
||||
icon: <DeleteOutlined />,
|
||||
disabled: disabledList?.includes('batchDelete'),
|
||||
},
|
||||
].filter((item) => {
|
||||
return !hiddenList.includes(item.key);
|
||||
});
|
||||
|
||||
const popoverConfig = {
|
||||
title: '选择下载区间',
|
||||
content: (
|
||||
<Space direction="vertical">
|
||||
<Radio.Group
|
||||
size="small"
|
||||
value={pickerType}
|
||||
onChange={(e) => {
|
||||
setPickerType(e.target.value);
|
||||
}}
|
||||
>
|
||||
<Radio.Button value="day">按日</Radio.Button>
|
||||
<Radio.Button value="week">按周</Radio.Button>
|
||||
<Radio.Button value="month">按月</Radio.Button>
|
||||
</Radio.Group>
|
||||
<RangePicker
|
||||
style={{ paddingBottom: 5 }}
|
||||
onChange={(date) => {
|
||||
dateRangeRef.current = date;
|
||||
return;
|
||||
}}
|
||||
picker={pickerType as any}
|
||||
allowClear={true}
|
||||
/>
|
||||
<div style={{ marginTop: 20 }}>
|
||||
<Space>
|
||||
<Button
|
||||
type="primary"
|
||||
loading={downloadLoading}
|
||||
onClick={() => {
|
||||
const [startMoment, endMoment] = dateRangeRef.current;
|
||||
let searchDateRange = [
|
||||
startMoment?.format('YYYY-MM-DD'),
|
||||
endMoment?.format('YYYY-MM-DD'),
|
||||
];
|
||||
if (pickerType === 'week') {
|
||||
searchDateRange = [
|
||||
startMoment?.startOf('isoWeek').format('YYYY-MM-DD'),
|
||||
endMoment?.startOf('isoWeek').format('YYYY-MM-DD'),
|
||||
];
|
||||
}
|
||||
if (pickerType === 'month') {
|
||||
searchDateRange = [
|
||||
startMoment?.startOf('month').format('YYYY-MM-DD'),
|
||||
endMoment?.startOf('month').format('YYYY-MM-DD'),
|
||||
];
|
||||
}
|
||||
onDownloadDateRangeChange?.(searchDateRange, pickerType);
|
||||
}}
|
||||
>
|
||||
下载
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
<Popover
|
||||
content={popoverConfig?.content}
|
||||
title={popoverConfig?.title}
|
||||
trigger="click"
|
||||
key="ctrlBtnList"
|
||||
open={popoverOpenState}
|
||||
placement="bottomLeft"
|
||||
onOpenChange={(open: boolean) => {
|
||||
setPopoverOpenState(open);
|
||||
}}
|
||||
>
|
||||
<Dropdown.Button
|
||||
menu={{
|
||||
items: dropdownButtonItems,
|
||||
onClick: ({ key }: { key: string }) => {
|
||||
onMenuClick?.(key);
|
||||
},
|
||||
}}
|
||||
>
|
||||
批量操作
|
||||
</Dropdown.Button>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
export default BatchCtrlDropDownButton;
|
||||
@@ -1,12 +1,13 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
|
||||
.container > * {
|
||||
background-color: @popover-bg;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: @shadow-1-down;
|
||||
box-shadow: 0 6px 16px -8px rgba(0, 0, 0, 0.08), 0 9px 28px 0 rgba(0, 0, 0, 0.05),
|
||||
0 12px 48px 16px rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-xs) {
|
||||
@media screen and (max-width: 480px) {
|
||||
.container {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
30
webapp/packages/supersonic-fe/src/components/MStar/index.tsx
Normal file
30
webapp/packages/supersonic-fe/src/components/MStar/index.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { StarOutlined, StarFilled } from '@ant-design/icons';
|
||||
import styles from './style.less';
|
||||
|
||||
type Props = {
|
||||
star?: boolean;
|
||||
onToggleCollect: (star: boolean) => void;
|
||||
};
|
||||
|
||||
const MStar: React.FC<Props> = ({ star = false, onToggleCollect }) => {
|
||||
const [starState, setStarState] = useState(star);
|
||||
useEffect(() => {
|
||||
setStarState(star);
|
||||
}, [star]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${styles.collectDashboard} ${starState === true ? 'dashboardCollected' : ''}`}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
setStarState(!starState);
|
||||
onToggleCollect(!starState);
|
||||
}}
|
||||
>
|
||||
{starState === false ? <StarOutlined /> : <StarFilled style={{ color: '#eac54f' }} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MStar;
|
||||
@@ -0,0 +1,6 @@
|
||||
.collectDashboard {
|
||||
color: #546174;
|
||||
&.dashboardCollected {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ const AvatarDropdown: React.FC<GlobalHeaderRightProps> = () => {
|
||||
<HeaderDropdown menu={{ items }} disabled={APP_TARGET === 'inner'}>
|
||||
<span className={`${styles.action} ${styles.account}`}>
|
||||
<TMEAvatar className={styles.avatar} size="small" staffName={currentUser.staffName} />
|
||||
<span className={cx(styles.name, 'anticon')}>{currentUser.staffName}</span>
|
||||
<span style={{ color: '#fff' }}>{currentUser.staffName}</span>
|
||||
</span>
|
||||
</HeaderDropdown>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
|
||||
@pro-header-hover-bg: rgba(0, 0, 0, 0.025);
|
||||
|
||||
@@ -26,15 +26,17 @@
|
||||
padding: 0 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
color: #fff;
|
||||
>span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
&:hover {
|
||||
background: @pro-header-hover-bg;
|
||||
background: #296df3;
|
||||
}
|
||||
|
||||
|
||||
&:global(.opened) {
|
||||
background: @pro-header-hover-bg;
|
||||
}
|
||||
@@ -57,49 +59,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
.action {
|
||||
.download {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menuName {
|
||||
margin-left: 5px;
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #296df3;
|
||||
}
|
||||
|
||||
&:global(.opened) {
|
||||
background: #252a3d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIcon {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.tooltip {
|
||||
padding-top: 0 !important;
|
||||
font-size: 12px !important;
|
||||
|
||||
:global {
|
||||
.ant-tooltip-arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-tooltip-inner {
|
||||
min-height: 0 !important;
|
||||
padding: 3px 6px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import Avatar from './AvatarDropdown';
|
||||
import { SettingOutlined } from '@ant-design/icons';
|
||||
import { getSystemConfig } from '@/services/user';
|
||||
import styles from './index.less';
|
||||
import cx from 'classnames';
|
||||
|
||||
export type SiderTheme = 'light' | 'dark';
|
||||
|
||||
@@ -21,27 +20,20 @@ const GlobalHeaderRight: React.FC = () => {
|
||||
}
|
||||
const { currentUser = {} } = initialState as any;
|
||||
|
||||
const { layout } = initialState.settings;
|
||||
let className = styles.right;
|
||||
|
||||
const querySystemConfig = async () => {
|
||||
const { code, data } = await getSystemConfig();
|
||||
if (code === 200) {
|
||||
const { admins } = data;
|
||||
if (admins.includes(currentUser?.staffName)) {
|
||||
if (Array.isArray(admins) && admins.includes(currentUser?.staffName)) {
|
||||
setHasSettingPermisson(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (layout === 'top' || layout === 'mix') {
|
||||
className = cx(styles.right, styles.dark);
|
||||
}
|
||||
|
||||
function handleLogin() {}
|
||||
|
||||
return (
|
||||
<Space className={className} style={{ marginRight: -8 }}>
|
||||
<Space className={styles.right}>
|
||||
<Avatar onClickLogin={handleLogin} />
|
||||
{hasSettingPermisson && (
|
||||
<span
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.standardFormRow {
|
||||
display: flex;
|
||||
@@ -15,7 +14,7 @@
|
||||
.ant-legacy-form-item-label {
|
||||
label {
|
||||
margin-right: 0;
|
||||
color: @text-color;
|
||||
color: fade(#000, 85%);
|
||||
}
|
||||
}
|
||||
.ant-form-item-label,
|
||||
@@ -29,8 +28,8 @@
|
||||
.label {
|
||||
flex: 0 0 auto;
|
||||
margin-right: 12px;
|
||||
color: @heading-color;
|
||||
font-size: @font-size-base;
|
||||
color: fade(#000, 85%);
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
& > span {
|
||||
display: inline-block;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.tagSelect {
|
||||
position: relative;
|
||||
@@ -12,7 +11,7 @@
|
||||
.ant-tag {
|
||||
margin-right: 24px;
|
||||
padding: 0 8px;
|
||||
font-size: @font-size-base;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
&.expanded {
|
||||
|
||||
Reference in New Issue
Block a user