refactor: Migrate HeaderActionsDropdown to typescript (#30568)

This commit is contained in:
Enzo Martellucci 2024-10-22 15:55:07 +02:00 committed by GitHub
parent 4d5f70c694
commit 4433ef47fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 55 additions and 87 deletions

View File

@ -66,9 +66,13 @@ const createProps = (): HeaderDropdownProps => ({
userCanCurate: false,
lastModifiedTime: 0,
isDropdownVisible: true,
setIsDropdownVisible: jest.fn(),
directPathToChild: [],
manageEmbedded: jest.fn(),
dataMask: {},
logEvent: jest.fn(),
refreshLimit: 0,
refreshWarning: '',
});
const editModeOnProps = {

View File

@ -17,7 +17,6 @@
* under the License.
*/
import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { isEmpty } from 'lodash';
import { connect } from 'react-redux';
import { t } from '@superset-ui/core';
@ -35,73 +34,38 @@ import FilterScopeModal from 'src/dashboard/components/filterscope/FilterScopeMo
import getDashboardUrl from 'src/dashboard/util/getDashboardUrl';
import { getActiveFilters } from 'src/dashboard/util/activeDashboardFilters';
import { getUrlParam } from 'src/utils/urlUtils';
import { MenuKeys } from 'src/dashboard/types';
import { MenuKeys, RootState } from 'src/dashboard/types';
import { HeaderDropdownProps } from 'src/dashboard/components/Header/types';
const propTypes = {
addSuccessToast: PropTypes.func.isRequired,
addDangerToast: PropTypes.func.isRequired,
dashboardInfo: PropTypes.object.isRequired,
dashboardId: PropTypes.number,
dashboardTitle: PropTypes.string,
dataMask: PropTypes.object.isRequired,
customCss: PropTypes.string,
colorNamespace: PropTypes.string,
colorScheme: PropTypes.string,
directPathToChild: PropTypes.array,
onChange: PropTypes.func.isRequired,
updateCss: PropTypes.func.isRequired,
forceRefreshAllCharts: PropTypes.func.isRequired,
refreshFrequency: PropTypes.number,
shouldPersistRefreshFrequency: PropTypes.bool.isRequired,
setRefreshFrequency: PropTypes.func.isRequired,
startPeriodicRender: PropTypes.func.isRequired,
editMode: PropTypes.bool.isRequired,
userCanEdit: PropTypes.bool,
userCanShare: PropTypes.bool,
userCanSave: PropTypes.bool,
userCanCurate: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,
layout: PropTypes.object.isRequired,
expandedSlices: PropTypes.object,
onSave: PropTypes.func.isRequired,
showPropertiesModal: PropTypes.func.isRequired,
manageEmbedded: PropTypes.func.isRequired,
logEvent: PropTypes.func,
refreshLimit: PropTypes.number,
refreshWarning: PropTypes.string,
lastModifiedTime: PropTypes.number.isRequired,
};
const defaultProps = {
colorNamespace: undefined,
colorScheme: undefined,
refreshLimit: 0,
refreshWarning: null,
};
const mapStateToProps = state => ({
const mapStateToProps = (state: RootState) => ({
directPathToChild: state.dashboardState.directPathToChild,
});
export class HeaderActionsDropdown extends PureComponent {
static discardChanges() {
window.location.reload();
}
interface HeaderActionsDropdownState {
css: string;
showReportSubMenu: boolean | null;
}
constructor(props) {
export class HeaderActionsDropdown extends PureComponent<
HeaderDropdownProps,
HeaderActionsDropdownState
> {
static defaultProps = {
colorNamespace: undefined,
colorScheme: undefined,
refreshLimit: 0,
refreshWarning: null,
};
constructor(props: HeaderDropdownProps) {
super(props);
this.state = {
css: props.customCss,
css: props.customCss || '',
showReportSubMenu: null,
};
this.changeCss = this.changeCss.bind(this);
this.changeRefreshInterval = this.changeRefreshInterval.bind(this);
this.handleMenuClick = this.handleMenuClick.bind(this);
this.setShowReportSubMenu = this.setShowReportSubMenu.bind(this);
}
UNSAFE_componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps: HeaderDropdownProps) {
if (this.props.customCss !== nextProps.customCss) {
this.setState({ css: nextProps.customCss }, () => {
injectCustomCss(nextProps.customCss);
@ -109,23 +73,21 @@ export class HeaderActionsDropdown extends PureComponent {
}
}
setShowReportSubMenu(show) {
this.setState({
showReportSubMenu: show,
});
}
setShowReportSubMenu = (show: boolean) => {
this.setState({ showReportSubMenu: show });
};
changeCss(css) {
changeCss = (css: string) => {
this.props.onChange();
this.props.updateCss(css);
}
};
changeRefreshInterval(refreshInterval, isPersistent) {
changeRefreshInterval = (refreshInterval: number, isPersistent: boolean) => {
this.props.setRefreshFrequency(refreshInterval, isPersistent);
this.props.startPeriodicRender(refreshInterval * 1000);
}
};
handleMenuClick({ key }) {
handleMenuClick = ({ key }: Record<string, any>) => {
switch (key) {
case MenuKeys.RefreshDashboard:
this.props.forceRefreshAllCharts();
@ -139,7 +101,7 @@ export class HeaderActionsDropdown extends PureComponent {
pathname: window.location.pathname,
filters: getActiveFilters(),
hash: window.location.hash,
standalone: !getUrlParam(URL_PARAMS.standalone),
standalone: getUrlParam(URL_PARAMS.standalone),
});
window.location.replace(url);
break;
@ -151,7 +113,7 @@ export class HeaderActionsDropdown extends PureComponent {
default:
break;
}
}
};
render() {
const {
@ -244,8 +206,8 @@ export class HeaderActionsDropdown extends PureComponent {
{userCanSave && (
<Menu.Item key={MenuKeys.SaveModal}>
<SaveModal
addSuccessToast={this.props.addSuccessToast}
addDangerToast={this.props.addDangerToast}
addSuccessToast={addSuccessToast}
addDangerToast={addDangerToast}
dashboardId={dashboardId}
dashboardTitle={dashboardTitle}
dashboardInfo={dashboardInfo}
@ -270,13 +232,13 @@ export class HeaderActionsDropdown extends PureComponent {
key={MenuKeys.Download}
disabled={isLoading}
title={t('Download')}
logEvent={this.props.logEvent}
>
<DownloadMenuItems
pdfMenuItemTitle={t('Export to PDF')}
imageMenuItemTitle={t('Download as Image')}
dashboardTitle={dashboardTitle}
dashboardId={dashboardId}
logEvent={this.props.logEvent}
/>
</Menu.SubMenu>
{userCanShare && (
@ -338,15 +300,16 @@ export class HeaderActionsDropdown extends PureComponent {
{editMode && !isEmpty(dashboardInfo?.metadata?.filter_scopes) && (
<Menu.Item key={MenuKeys.SetFilterMapping}>
<FilterScopeModal
className="m-r-5"
triggerNode={t('Set filter mapping')}
triggerNode={
<span className="m-r-5">{t('Set filter mapping')}</span>
}
/>
</Menu.Item>
)}
<Menu.Item key={MenuKeys.AutorefreshModal}>
<RefreshIntervalModal
addSuccessToast={this.props.addSuccessToast}
addSuccessToast={addSuccessToast}
refreshFrequency={refreshFrequency}
refreshLimit={refreshLimit}
refreshWarning={refreshWarning}
@ -361,7 +324,4 @@ export class HeaderActionsDropdown extends PureComponent {
}
}
HeaderActionsDropdown.propTypes = propTypes;
HeaderActionsDropdown.defaultProps = defaultProps;
export default connect(mapStateToProps)(HeaderActionsDropdown);

View File

@ -30,7 +30,7 @@ interface DashboardInfo {
}
export interface HeaderDropdownProps {
addSuccessToast: () => void;
addSuccessToast: (msg: string) => void;
addDangerToast: () => void;
customCss: string;
colorNamespace?: string;
@ -47,20 +47,24 @@ export interface HeaderDropdownProps {
onChange: () => void;
onSave: () => void;
refreshFrequency: number;
setRefreshFrequency: () => void;
setRefreshFrequency: (refreshInterval: number, isPersistent: boolean) => void;
shouldPersistRefreshFrequency: boolean;
showPropertiesModal: () => void;
startPeriodicRender: () => void;
updateCss: () => void;
startPeriodicRender: (interval: number) => void;
updateCss: (css: string) => void;
userCanEdit: boolean;
userCanSave: boolean;
userCanShare: boolean;
userCanCurate: boolean;
isDropdownVisible: boolean;
manageEmbedded: () => void;
dataMask: any;
lastModifiedTime: number;
logEvent: () => void;
setIsDropdownVisible: (visible: boolean) => void;
isDropdownVisible: boolean;
refreshLimit: number;
refreshWarning: string;
directPathToChild: string[];
}
export interface HeaderProps {

View File

@ -24,7 +24,7 @@ const createProps = () => ({
imageMenuItemTitle: 'Download as Image',
dashboardTitle: 'Test Dashboard',
logEvent: jest.fn(),
dashboardId: '123',
dashboardId: 123,
});
const renderComponent = () => {

View File

@ -42,7 +42,7 @@ jest.mock('src/components/MessageToasts/withToasts', () => ({
const defaultProps = () => ({
text: 'Download',
dashboardId: '123',
dashboardId: 123,
format: DownloadScreenshotFormat.PDF,
logEvent: mockLogEvent,
});

View File

@ -45,7 +45,7 @@ export default function DownloadScreenshot({
...rest
}: {
text: string;
dashboardId: string;
dashboardId: number;
logEvent?: Function;
format: string;
}) {

View File

@ -25,7 +25,7 @@ export interface DownloadMenuItemProps {
imageMenuItemTitle: string;
dashboardTitle: string;
logEvent?: Function;
dashboardId: string;
dashboardId: number;
}
const DownloadMenuItems = (props: DownloadMenuItemProps) => {