Skip to content

Commit 4433ef4

Browse files
authored
refactor: Migrate HeaderActionsDropdown to typescript (#30568)
1 parent 4d5f70c commit 4433ef4

File tree

7 files changed

+55
-87
lines changed

7 files changed

+55
-87
lines changed

superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,13 @@ const createProps = (): HeaderDropdownProps => ({
6666
userCanCurate: false,
6767
lastModifiedTime: 0,
6868
isDropdownVisible: true,
69+
setIsDropdownVisible: jest.fn(),
70+
directPathToChild: [],
6971
manageEmbedded: jest.fn(),
7072
dataMask: {},
7173
logEvent: jest.fn(),
74+
refreshLimit: 0,
75+
refreshWarning: '',
7276
});
7377

7478
const editModeOnProps = {

superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx renamed to superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.tsx

Lines changed: 38 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
* under the License.
1818
*/
1919
import { PureComponent } from 'react';
20-
import PropTypes from 'prop-types';
2120
import { isEmpty } from 'lodash';
2221
import { connect } from 'react-redux';
2322
import { t } from '@superset-ui/core';
@@ -35,97 +34,60 @@ import FilterScopeModal from 'src/dashboard/components/filterscope/FilterScopeMo
3534
import getDashboardUrl from 'src/dashboard/util/getDashboardUrl';
3635
import { getActiveFilters } from 'src/dashboard/util/activeDashboardFilters';
3736
import { getUrlParam } from 'src/utils/urlUtils';
38-
import { MenuKeys } from 'src/dashboard/types';
37+
import { MenuKeys, RootState } from 'src/dashboard/types';
38+
import { HeaderDropdownProps } from 'src/dashboard/components/Header/types';
3939

40-
const propTypes = {
41-
addSuccessToast: PropTypes.func.isRequired,
42-
addDangerToast: PropTypes.func.isRequired,
43-
dashboardInfo: PropTypes.object.isRequired,
44-
dashboardId: PropTypes.number,
45-
dashboardTitle: PropTypes.string,
46-
dataMask: PropTypes.object.isRequired,
47-
customCss: PropTypes.string,
48-
colorNamespace: PropTypes.string,
49-
colorScheme: PropTypes.string,
50-
directPathToChild: PropTypes.array,
51-
onChange: PropTypes.func.isRequired,
52-
updateCss: PropTypes.func.isRequired,
53-
forceRefreshAllCharts: PropTypes.func.isRequired,
54-
refreshFrequency: PropTypes.number,
55-
shouldPersistRefreshFrequency: PropTypes.bool.isRequired,
56-
setRefreshFrequency: PropTypes.func.isRequired,
57-
startPeriodicRender: PropTypes.func.isRequired,
58-
editMode: PropTypes.bool.isRequired,
59-
userCanEdit: PropTypes.bool,
60-
userCanShare: PropTypes.bool,
61-
userCanSave: PropTypes.bool,
62-
userCanCurate: PropTypes.bool.isRequired,
63-
isLoading: PropTypes.bool.isRequired,
64-
layout: PropTypes.object.isRequired,
65-
expandedSlices: PropTypes.object,
66-
onSave: PropTypes.func.isRequired,
67-
showPropertiesModal: PropTypes.func.isRequired,
68-
manageEmbedded: PropTypes.func.isRequired,
69-
logEvent: PropTypes.func,
70-
refreshLimit: PropTypes.number,
71-
refreshWarning: PropTypes.string,
72-
lastModifiedTime: PropTypes.number.isRequired,
73-
};
74-
75-
const defaultProps = {
76-
colorNamespace: undefined,
77-
colorScheme: undefined,
78-
refreshLimit: 0,
79-
refreshWarning: null,
80-
};
81-
82-
const mapStateToProps = state => ({
40+
const mapStateToProps = (state: RootState) => ({
8341
directPathToChild: state.dashboardState.directPathToChild,
8442
});
8543

86-
export class HeaderActionsDropdown extends PureComponent {
87-
static discardChanges() {
88-
window.location.reload();
89-
}
44+
interface HeaderActionsDropdownState {
45+
css: string;
46+
showReportSubMenu: boolean | null;
47+
}
9048

91-
constructor(props) {
49+
export class HeaderActionsDropdown extends PureComponent<
50+
HeaderDropdownProps,
51+
HeaderActionsDropdownState
52+
> {
53+
static defaultProps = {
54+
colorNamespace: undefined,
55+
colorScheme: undefined,
56+
refreshLimit: 0,
57+
refreshWarning: null,
58+
};
59+
60+
constructor(props: HeaderDropdownProps) {
9261
super(props);
9362
this.state = {
94-
css: props.customCss,
63+
css: props.customCss || '',
9564
showReportSubMenu: null,
9665
};
97-
98-
this.changeCss = this.changeCss.bind(this);
99-
this.changeRefreshInterval = this.changeRefreshInterval.bind(this);
100-
this.handleMenuClick = this.handleMenuClick.bind(this);
101-
this.setShowReportSubMenu = this.setShowReportSubMenu.bind(this);
10266
}
10367

104-
UNSAFE_componentWillReceiveProps(nextProps) {
68+
UNSAFE_componentWillReceiveProps(nextProps: HeaderDropdownProps) {
10569
if (this.props.customCss !== nextProps.customCss) {
10670
this.setState({ css: nextProps.customCss }, () => {
10771
injectCustomCss(nextProps.customCss);
10872
});
10973
}
11074
}
11175

112-
setShowReportSubMenu(show) {
113-
this.setState({
114-
showReportSubMenu: show,
115-
});
116-
}
76+
setShowReportSubMenu = (show: boolean) => {
77+
this.setState({ showReportSubMenu: show });
78+
};
11779

118-
changeCss(css) {
80+
changeCss = (css: string) => {
11981
this.props.onChange();
12082
this.props.updateCss(css);
121-
}
83+
};
12284

123-
changeRefreshInterval(refreshInterval, isPersistent) {
85+
changeRefreshInterval = (refreshInterval: number, isPersistent: boolean) => {
12486
this.props.setRefreshFrequency(refreshInterval, isPersistent);
12587
this.props.startPeriodicRender(refreshInterval * 1000);
126-
}
88+
};
12789

128-
handleMenuClick({ key }) {
90+
handleMenuClick = ({ key }: Record<string, any>) => {
12991
switch (key) {
13092
case MenuKeys.RefreshDashboard:
13193
this.props.forceRefreshAllCharts();
@@ -139,7 +101,7 @@ export class HeaderActionsDropdown extends PureComponent {
139101
pathname: window.location.pathname,
140102
filters: getActiveFilters(),
141103
hash: window.location.hash,
142-
standalone: !getUrlParam(URL_PARAMS.standalone),
104+
standalone: getUrlParam(URL_PARAMS.standalone),
143105
});
144106
window.location.replace(url);
145107
break;
@@ -151,7 +113,7 @@ export class HeaderActionsDropdown extends PureComponent {
151113
default:
152114
break;
153115
}
154-
}
116+
};
155117

156118
render() {
157119
const {
@@ -244,8 +206,8 @@ export class HeaderActionsDropdown extends PureComponent {
244206
{userCanSave && (
245207
<Menu.Item key={MenuKeys.SaveModal}>
246208
<SaveModal
247-
addSuccessToast={this.props.addSuccessToast}
248-
addDangerToast={this.props.addDangerToast}
209+
addSuccessToast={addSuccessToast}
210+
addDangerToast={addDangerToast}
249211
dashboardId={dashboardId}
250212
dashboardTitle={dashboardTitle}
251213
dashboardInfo={dashboardInfo}
@@ -270,13 +232,13 @@ export class HeaderActionsDropdown extends PureComponent {
270232
key={MenuKeys.Download}
271233
disabled={isLoading}
272234
title={t('Download')}
273-
logEvent={this.props.logEvent}
274235
>
275236
<DownloadMenuItems
276237
pdfMenuItemTitle={t('Export to PDF')}
277238
imageMenuItemTitle={t('Download as Image')}
278239
dashboardTitle={dashboardTitle}
279240
dashboardId={dashboardId}
241+
logEvent={this.props.logEvent}
280242
/>
281243
</Menu.SubMenu>
282244
{userCanShare && (
@@ -338,15 +300,16 @@ export class HeaderActionsDropdown extends PureComponent {
338300
{editMode && !isEmpty(dashboardInfo?.metadata?.filter_scopes) && (
339301
<Menu.Item key={MenuKeys.SetFilterMapping}>
340302
<FilterScopeModal
341-
className="m-r-5"
342-
triggerNode={t('Set filter mapping')}
303+
triggerNode={
304+
<span className="m-r-5">{t('Set filter mapping')}</span>
305+
}
343306
/>
344307
</Menu.Item>
345308
)}
346309

347310
<Menu.Item key={MenuKeys.AutorefreshModal}>
348311
<RefreshIntervalModal
349-
addSuccessToast={this.props.addSuccessToast}
312+
addSuccessToast={addSuccessToast}
350313
refreshFrequency={refreshFrequency}
351314
refreshLimit={refreshLimit}
352315
refreshWarning={refreshWarning}
@@ -361,7 +324,4 @@ export class HeaderActionsDropdown extends PureComponent {
361324
}
362325
}
363326

364-
HeaderActionsDropdown.propTypes = propTypes;
365-
HeaderActionsDropdown.defaultProps = defaultProps;
366-
367327
export default connect(mapStateToProps)(HeaderActionsDropdown);

superset-frontend/src/dashboard/components/Header/types.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ interface DashboardInfo {
3030
}
3131

3232
export interface HeaderDropdownProps {
33-
addSuccessToast: () => void;
33+
addSuccessToast: (msg: string) => void;
3434
addDangerToast: () => void;
3535
customCss: string;
3636
colorNamespace?: string;
@@ -47,20 +47,24 @@ export interface HeaderDropdownProps {
4747
onChange: () => void;
4848
onSave: () => void;
4949
refreshFrequency: number;
50-
setRefreshFrequency: () => void;
50+
setRefreshFrequency: (refreshInterval: number, isPersistent: boolean) => void;
5151
shouldPersistRefreshFrequency: boolean;
5252
showPropertiesModal: () => void;
53-
startPeriodicRender: () => void;
54-
updateCss: () => void;
53+
startPeriodicRender: (interval: number) => void;
54+
updateCss: (css: string) => void;
5555
userCanEdit: boolean;
5656
userCanSave: boolean;
5757
userCanShare: boolean;
5858
userCanCurate: boolean;
59-
isDropdownVisible: boolean;
6059
manageEmbedded: () => void;
6160
dataMask: any;
6261
lastModifiedTime: number;
6362
logEvent: () => void;
63+
setIsDropdownVisible: (visible: boolean) => void;
64+
isDropdownVisible: boolean;
65+
refreshLimit: number;
66+
refreshWarning: string;
67+
directPathToChild: string[];
6468
}
6569

6670
export interface HeaderProps {

superset-frontend/src/dashboard/components/menu/DownloadMenuItems/DownloadMenuItems.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const createProps = () => ({
2424
imageMenuItemTitle: 'Download as Image',
2525
dashboardTitle: 'Test Dashboard',
2626
logEvent: jest.fn(),
27-
dashboardId: '123',
27+
dashboardId: 123,
2828
});
2929

3030
const renderComponent = () => {

superset-frontend/src/dashboard/components/menu/DownloadMenuItems/DownloadScreenshot.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jest.mock('src/components/MessageToasts/withToasts', () => ({
4242

4343
const defaultProps = () => ({
4444
text: 'Download',
45-
dashboardId: '123',
45+
dashboardId: 123,
4646
format: DownloadScreenshotFormat.PDF,
4747
logEvent: mockLogEvent,
4848
});

superset-frontend/src/dashboard/components/menu/DownloadMenuItems/DownloadScreenshot.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default function DownloadScreenshot({
4545
...rest
4646
}: {
4747
text: string;
48-
dashboardId: string;
48+
dashboardId: number;
4949
logEvent?: Function;
5050
format: string;
5151
}) {

superset-frontend/src/dashboard/components/menu/DownloadMenuItems/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface DownloadMenuItemProps {
2525
imageMenuItemTitle: string;
2626
dashboardTitle: string;
2727
logEvent?: Function;
28-
dashboardId: string;
28+
dashboardId: number;
2929
}
3030

3131
const DownloadMenuItems = (props: DownloadMenuItemProps) => {

0 commit comments

Comments
 (0)