Skip to content

feat(dashboard): Add button component with URL, dashboard, and data chart navigation #2203

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

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
212 changes: 212 additions & 0 deletions frontend/src/app/components/FormGenerator/Customize/BtnFormat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import { Input, Radio, Select, Space, Switch, Typography } from 'antd';
import { FC, memo, useEffect } from 'react';
import { ChartStyleConfig } from '../../../types/ChartConfig';

import { ItemLayoutProps } from '../types';
import { updateByKey } from '../../../utils/mutation';
import { IconList } from '../../../pages/DashBoardPage/components/Widgets/CustomBtnWidget/util/Icon';

const BtnFormat: FC<ItemLayoutProps<ChartStyleConfig>> = memo(
({ ancestors, translate: t = title => title, data, onChange, context }) => {
const TextSecondary = props => (
<Typography.Text type={'secondary'} {...props} />
);

const handleSettingChange = key => e => {
const val = e.target.value;
handleSettingChangeWithValue(key)(val);
};

const handleSettingChangeWithValue = key => val => {
const newData = updateByKey(
data,
'value',
Object.assign({}, data.value, { [key]: val }),
);
onChange?.(ancestors, newData);
};

const BtnTypes = [
{
name: '默认',
value: 'default',
},
{
name: '主要',
value: 'primary',
},
{
name: '文字',
value: 'text',
},
{
name: '链接',
value: 'link',
},
{
name: '虚线',
value: 'dashed',
},
];

const BtnSizes = [
{
name: '大',
value: 'large',
},
{
name: '中',
value: 'middle',
},
{
name: '小',
value: 'small',
},
];

return (
<Space direction={'vertical'}>
<Space direction={'vertical'}>
<TextSecondary>按钮文字</TextSecondary>
<Input
value={data.value?.content}
style={{ width: '100%' }}
onChange={handleSettingChange('content')}
className={'datart-antd-input'}
/>
</Space>
<Space direction={'vertical'}>
<TextSecondary>按钮类型</TextSecondary>
<Select
value={data.value?.btnType}
style={{ minWidth: '100%' }}
onChange={handleSettingChangeWithValue('btnType')}
>
{BtnTypes.map(ele => (
<Select.Option key={ele.value} value={ele.value}>
{ele.name}
</Select.Option>
))}
</Select>
</Space>
<Space direction={'vertical'}>
<TextSecondary>危险操作</TextSecondary>
<Switch
checked={data.value?.danger}
style={{ minWidth: '100%' }}
onChange={handleSettingChangeWithValue('danger')}
/>
</Space>
<Space direction={'vertical'}>
<TextSecondary>按钮图标</TextSecondary>
<Select
value={data.value?.icon}
placeholder={'Ant Design的图标'}
style={{ minWidth: 150 }}
showSearch={true}
onChange={handleSettingChangeWithValue('icon')}
options={IconList}
/>
</Space>
<Space direction={'vertical'}>
<TextSecondary>按钮大小</TextSecondary>
<Select
value={data.value?.btnSize}
style={{ minWidth: '100%' }}
onChange={handleSettingChangeWithValue('btnSize')}
>
{BtnSizes.map(ele => (
<Select.Option key={ele.value} value={ele.value}>
{ele.name}
</Select.Option>
))}
</Select>
</Space>
<Space direction={'vertical'}>
<TextSecondary>跳转设置</TextSecondary>
<Radio.Group
value={data.value?.jumpType}
onChange={handleSettingChange('jumpType')}
>
<Radio.Button value={'url'}>URL</Radio.Button>
<Radio.Button value={'dashboard'}>仪表板</Radio.Button>
<Radio.Button value={'datachart'}>图表</Radio.Button>
</Radio.Group>
</Space>
{data.value?.jumpType && (
<Space direction={'vertical'}>
<TextSecondary>打开方式</TextSecondary>
<Radio.Group
value={data.value?.target}
onChange={handleSettingChange('target')}
>
<Radio.Button value={'_blank'}>新窗口</Radio.Button>
<Radio.Button value={'_self'}>当前页</Radio.Button>
</Radio.Group>
</Space>
)}
{data.value?.jumpType === 'url' && (
<Space direction={'vertical'}>
<TextSecondary>URL</TextSecondary>
<Input.TextArea
value={data.value?.href}
style={{ minWidth: '100%' }}
onChange={handleSettingChange('href')}
className={'datart-antd-input'}
/>
</Space>
)}
{data.value?.jumpType === 'dashboard' && (
<Space direction={'vertical'}>
<TextSecondary>仪表板</TextSecondary>
<Select
virtual
showSearch
value={data.value?.dashboardId}
style={{ minWidth: 100, maxWidth: 200 }}
dropdownMatchSelectWidth={false}
onChange={handleSettingChangeWithValue('dashboardId')}
className={'datart-antd-input'}
>
{context?.vizs
?.filter(v => v.relType === 'DASHBOARD')
?.map(c => {
return (
<Select.Option key={c.relId} value={c.relId}>
{c.name}
</Select.Option>
);
})}
</Select>
</Space>
)}
{data.value?.jumpType === 'datachart' && (
<Space direction={'vertical'}>
<TextSecondary>图表</TextSecondary>
<Select
virtual
showSearch
value={data.value?.datachartId}
style={{ minWidth: 100, maxWidth: 200 }}
dropdownMatchSelectWidth={false}
onChange={handleSettingChangeWithValue('datachartId')}
className={'datart-antd-input'}
>
{context?.vizs
?.filter(v => v.relType === 'DATACHART')
?.map(c => {
return (
<Select.Option key={c.relId} value={c.relId}>
{c.name}
</Select.Option>
);
})}
</Select>
</Space>
)}
</Space>
);
},
);

export default BtnFormat;
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ export { default as TimerFormat } from './TimerFormat';
export { default as UnControlledTableHeaderPanel } from './UnControlledTableHeaderPanel';
export { default as WidgetBorder } from './WidgetBorder';
export { default as YAxisNumberFormatPanel } from './YAxisNumberFormatPanel';
export { default as BtnFormat } from './BtnFormat';
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import {
ViewDetailPanel,
WidgetBorder,
YAxisNumberFormatPanel,
BtnFormat,
} from '../Customize';
import { FormGeneratorLayoutProps } from '../types';
import { groupLayoutComparer, invokeDependencyWatcher } from '../utils';
Expand Down Expand Up @@ -216,6 +217,8 @@ const ItemLayout: FC<FormGeneratorLayoutProps<ChartStyleConfig>> = memo(
return <DataZoomPanel {...props} />;
case ChartStyleSectionComponentType.Y_AXIS_NUMBER_FORMAT_PANEL:
return <YAxisNumberFormatPanel {...props} />;
case ChartStyleSectionComponentType.BTN_FORMAT:
return <BtnFormat {...props} />;
default:
return <div>{`no matched component comType of ${data.comType}`}</div>;
}
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/app/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

import { FONT_FAMILY, G90 } from 'styles/StyleConstants';
import { IFontDefault } from 'types';
import { ICustomBtnDefault, IFontDefault } from 'types';

export enum TenantManagementMode {
Team = 'TEAM',
Expand Down Expand Up @@ -215,6 +215,7 @@ export const ChartStyleSectionComponentType = {
TEXT: 'text',
CONDITIONAL_STYLE: 'conditionalStylePanel',
RADIO: 'radio',
BTN_FORMAT: 'btnFormat',

// Customize Component
FONT_ALIGNMENT: 'fontAlignment',
Expand Down Expand Up @@ -253,6 +254,13 @@ export const FONT_DEFAULT: IFontDefault = {
color: G90,
};

export const CUSTOM_BTN_DEFAULT: ICustomBtnDefault = {
btnSize: 'middle',
btnType: 'default',
content: '按钮',
danger: false,
};

export enum AuthorizationStatus {
Initialized = 'initialized',
Pending = 'pending',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import tabProto from '../Widgets/TabWidget/tabConfig';
import timerProto from '../Widgets/TimerWidget/timerConfig';
import videoProto from '../Widgets/VideoWidget/videoConfig';
import { widgetManagerInstance as widgetManager } from './WidgetManager';
import customBtnProto from '../Widgets/CustomBtnWidget/customBtnConfig';

const protoList: WidgetProto[] = [
linkedChartProto, // chart
Expand All @@ -57,6 +58,7 @@ const protoList: WidgetProto[] = [
radioGroupProto,
textProto,
timeProto,
customBtnProto,
dropDownTree,
rangeTimeProto,
rangeValueProto,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,18 @@ export const TitleI18N = {
},
},
};
export const initPaddingTpl = () => {
export const initPaddingTpl = (obj?: {
top?: number;
bottom?: number;
left?: number;
right?: number;
}) => {
const { top, bottom, left, right } = obj || {
top: 8,
bottom: 8,
left: 8,
right: 8,
};
const paddingTpl: ChartStyleConfig = {
label: 'padding.paddingGroup',
key: 'paddingGroup',
Expand All @@ -326,25 +337,25 @@ export const initPaddingTpl = () => {
{
label: 'padding.top',
key: 'top',
value: 8,
value: top,
comType: 'inputNumber',
},
{
label: 'padding.bottom',
key: 'bottom',
value: 8,
value: bottom,
comType: 'inputNumber',
},
{
label: 'padding.left',
key: 'left',
value: 8,
value: left,
comType: 'inputNumber',
},
{
label: 'padding.right',
key: 'right',
value: 8,
value: right,
comType: 'inputNumber',
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { RichTextWidget } from '../Widgets/RichTextWidget/RichTextWidget';
import { TabWidget } from '../Widgets/TabWidget/TabWidget';
import { TimerWidget } from '../Widgets/TimerWidget/TimerWidget';
import { VideoWidget } from '../Widgets/VideoWidget/VideoWidget';
import { CustomBtnWidget } from '../Widgets/CustomBtnWidget/CustomBtnWidget';

export const WidgetMapper: React.FC<{
boardEditing: boolean;
Expand Down Expand Up @@ -63,7 +64,8 @@ export const WidgetMapper: React.FC<{
return <IframeWidget hideTitle={hideTitle} />;
case ORIGINAL_TYPE_MAP.timer:
return <TimerWidget hideTitle={hideTitle} />;

case ORIGINAL_TYPE_MAP.customBtn:
return <CustomBtnWidget hideTitle={hideTitle} />;
// tab
case ORIGINAL_TYPE_MAP.tab:
return <TabWidget hideTitle={hideTitle} />;
Expand Down
Loading