You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2020/07/16 08:39:01 UTC
[incubator-superset] 03/06: chore: type welcome (#10317)
This is an automated email from the ASF dual-hosted git repository.
villebro pushed a commit to branch 0.37
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
commit 2f2fb47721d83f1bb377ee829532284be28d1753
Author: Erik Ritter <er...@airbnb.com>
AuthorDate: Wed Jul 15 08:38:43 2020 -0700
chore: type welcome (#10317)
---
superset-frontend/package-lock.json | 29 +++++++++++++
superset-frontend/package.json | 2 +
...boardTable_spec.jsx => DashboardTable_spec.tsx} | 2 +-
.../welcome/{Welcome_spec.jsx => Welcome_spec.tsx} | 14 ++++++-
superset-frontend/src/profile/components/App.tsx | 4 +-
.../src/profile/components/CreatedContent.tsx | 3 +-
.../src/profile/components/Favorites.tsx | 3 +-
.../src/profile/components/RecentActivity.tsx | 3 +-
.../src/profile/components/Security.tsx | 4 +-
.../src/profile/components/UserInfo.tsx | 4 +-
superset-frontend/src/profile/types.ts | 24 -----------
.../{profile/types.ts => types/bootstrapTypes.ts} | 28 ++++---------
superset-frontend/src/welcome/{App.jsx => App.tsx} | 2 +-
.../{DashboardTable.jsx => DashboardTable.tsx} | 48 ++++++++++++++++++----
.../src/welcome/{Welcome.jsx => Welcome.tsx} | 27 +++++++-----
.../src/welcome/{index.jsx => index.tsx} | 0
superset-frontend/webpack.config.js | 2 +-
17 files changed, 121 insertions(+), 78 deletions(-)
diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 135f6b4..aeabd74 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -7658,6 +7658,11 @@
"resolved": "https://registry.npmjs.org/@types/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha512-mky/O83TXmGY39P1H9YbUpjV6l6voRYlufqfFCvel8l1phuy8HRjdWc1rrPuN53ITBJlbyMSV6z3niOySO5pgQ=="
},
+ "@types/fetch-mock": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/@types/fetch-mock/-/fetch-mock-7.3.2.tgz",
+ "integrity": "sha512-NCEfv49jmDsBAixjMjEHKVgmVQlJ+uK56FOc+2roYPExnXCZDpi6mJOHQ3v23BiO84hBDStND9R2itJr7PNoow=="
+ },
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
@@ -7678,6 +7683,11 @@
"@types/node": "*"
}
},
+ "@types/history": {
+ "version": "4.7.6",
+ "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.6.tgz",
+ "integrity": "sha512-GRTZLeLJ8ia00ZH8mxMO8t0aC9M1N9bN461Z2eaRurJo6Fpa+utgCwLzI4jQHcrdzuzp5WPN9jRwpsCQ1VhJ5w=="
+ },
"@types/istanbul-lib-coverage": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -7837,6 +7847,25 @@
"redux": "^3.6.0"
}
},
+ "@types/react-router": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.8.tgz",
+ "integrity": "sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg==",
+ "requires": {
+ "@types/history": "*",
+ "@types/react": "*"
+ }
+ },
+ "@types/react-router-dom": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.5.tgz",
+ "integrity": "sha512-ArBM4B1g3BWLGbaGvwBGO75GNFbLDUthrDojV2vHLih/Tq8M+tgvY1DSwkuNrPSwdp/GUL93WSEpTZs8nVyJLw==",
+ "requires": {
+ "@types/history": "*",
+ "@types/react": "*",
+ "@types/react-router": "*"
+ }
+ },
"@types/react-select": {
"version": "3.0.12",
"resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-3.0.12.tgz",
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index 17fab51..742e82e 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -102,9 +102,11 @@
"@superset-ui/validator": "^0.14.9",
"@types/classnames": "^2.2.9",
"@types/enzyme": "^3.10.5",
+ "@types/fetch-mock": "^7.3.2",
"@types/react-bootstrap": "^0.32.21",
"@types/react-gravatar": "^2.6.8",
"@types/react-json-tree": "^0.6.11",
+ "@types/react-router-dom": "^5.1.5",
"@types/react-select": "^3.0.12",
"@types/react-virtualized": "^9.21.10",
"@types/react-window": "^1.8.2",
diff --git a/superset-frontend/spec/javascripts/welcome/DashboardTable_spec.jsx b/superset-frontend/spec/javascripts/welcome/DashboardTable_spec.tsx
similarity index 97%
rename from superset-frontend/spec/javascripts/welcome/DashboardTable_spec.jsx
rename to superset-frontend/spec/javascripts/welcome/DashboardTable_spec.tsx
index e9cf957..5ded3fa 100644
--- a/superset-frontend/spec/javascripts/welcome/DashboardTable_spec.jsx
+++ b/superset-frontend/spec/javascripts/welcome/DashboardTable_spec.tsx
@@ -55,7 +55,7 @@ describe('DashboardTable', () => {
expect(fetchMock.calls(dashboardsEndpoint)).toHaveLength(1);
// there's a delay between response and updating state, so manually set it
// rather than adding a timeout which could introduce flakiness
- wrapper.setState({ dashaboards: mockDashboards });
+ wrapper.setState({ dashboards: mockDashboards });
expect(wrapper.find(ListView)).toHaveLength(1);
done();
});
diff --git a/superset-frontend/spec/javascripts/welcome/Welcome_spec.jsx b/superset-frontend/spec/javascripts/welcome/Welcome_spec.tsx
similarity index 81%
rename from superset-frontend/spec/javascripts/welcome/Welcome_spec.jsx
rename to superset-frontend/spec/javascripts/welcome/Welcome_spec.tsx
index 763ff3e..0e7e5e1 100644
--- a/superset-frontend/spec/javascripts/welcome/Welcome_spec.jsx
+++ b/superset-frontend/spec/javascripts/welcome/Welcome_spec.tsx
@@ -23,11 +23,21 @@ import { shallow } from 'enzyme';
import Welcome from 'src/welcome/Welcome';
describe('Welcome', () => {
- const mockedProps = {};
+ const mockedProps = {
+ user: {
+ username: 'alpha',
+ firstName: 'alpha',
+ lastName: 'alpha',
+ createdOn: '2016-11-11T12:34:17',
+ userId: 5,
+ email: 'alpha@alpha.com',
+ isActive: true,
+ },
+ };
it('is valid', () => {
expect(React.isValidElement(<Welcome {...mockedProps} />)).toBe(true);
});
- it('renders 4 Tab, Panel, and Row components', () => {
+ it('renders 3 Tab, Panel, and Row components', () => {
const wrapper = shallow(<Welcome {...mockedProps} />);
expect(wrapper.find(Tab)).toHaveLength(3);
expect(wrapper.find(Panel)).toHaveLength(3);
diff --git a/superset-frontend/src/profile/components/App.tsx b/superset-frontend/src/profile/components/App.tsx
index bde67ac..470bf73 100644
--- a/superset-frontend/src/profile/components/App.tsx
+++ b/superset-frontend/src/profile/components/App.tsx
@@ -25,10 +25,10 @@ import UserInfo from './UserInfo';
import Security from './Security';
import RecentActivity from './RecentActivity';
import CreatedContent from './CreatedContent';
-import { User } from '../types';
+import { UserWithPermissionsAndRoles } from '../../types/bootstrapTypes';
interface AppProps {
- user: User;
+ user: UserWithPermissionsAndRoles;
}
export default function App({ user }: AppProps) {
diff --git a/superset-frontend/src/profile/components/CreatedContent.tsx b/superset-frontend/src/profile/components/CreatedContent.tsx
index 9831e4d..933b3e6 100644
--- a/superset-frontend/src/profile/components/CreatedContent.tsx
+++ b/superset-frontend/src/profile/components/CreatedContent.tsx
@@ -21,7 +21,8 @@ import moment from 'moment';
import { t } from '@superset-ui/translation';
import TableLoader from '../../components/TableLoader';
-import { User, Dashboard, Slice } from '../types';
+import { Slice } from '../types';
+import { User, Dashboard } from '../../types/bootstrapTypes';
interface CreatedContentProps {
user: User;
diff --git a/superset-frontend/src/profile/components/Favorites.tsx b/superset-frontend/src/profile/components/Favorites.tsx
index 89b4cc4..ca059f4 100644
--- a/superset-frontend/src/profile/components/Favorites.tsx
+++ b/superset-frontend/src/profile/components/Favorites.tsx
@@ -21,7 +21,8 @@ import moment from 'moment';
import { t } from '@superset-ui/translation';
import TableLoader from '../../components/TableLoader';
-import { User, Dashboard, Slice } from '../types';
+import { Slice } from '../types';
+import { User, Dashboard } from '../../types/bootstrapTypes';
interface FavoritesProps {
user: User;
diff --git a/superset-frontend/src/profile/components/RecentActivity.tsx b/superset-frontend/src/profile/components/RecentActivity.tsx
index 34f419c..30faf97 100644
--- a/superset-frontend/src/profile/components/RecentActivity.tsx
+++ b/superset-frontend/src/profile/components/RecentActivity.tsx
@@ -20,7 +20,8 @@ import React from 'react';
import moment from 'moment';
import TableLoader from '../../components/TableLoader';
-import { User, Activity } from '../types';
+import { Activity } from '../types';
+import { User } from '../../types/bootstrapTypes';
interface RecentActivityProps {
user: User;
diff --git a/superset-frontend/src/profile/components/Security.tsx b/superset-frontend/src/profile/components/Security.tsx
index 91b0284..9646fa1 100644
--- a/superset-frontend/src/profile/components/Security.tsx
+++ b/superset-frontend/src/profile/components/Security.tsx
@@ -19,10 +19,10 @@
import React from 'react';
import { Badge, Label } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
-import { User } from '../types';
+import { UserWithPermissionsAndRoles } from '../../types/bootstrapTypes';
interface SecurityProps {
- user: User;
+ user: UserWithPermissionsAndRoles;
}
export default function Security({ user }: SecurityProps) {
diff --git a/superset-frontend/src/profile/components/UserInfo.tsx b/superset-frontend/src/profile/components/UserInfo.tsx
index ccc1c89..ffc4179 100644
--- a/superset-frontend/src/profile/components/UserInfo.tsx
+++ b/superset-frontend/src/profile/components/UserInfo.tsx
@@ -21,10 +21,10 @@ import Gravatar from 'react-gravatar';
import moment from 'moment';
import { Panel } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
-import { User } from '../types';
+import { UserWithPermissionsAndRoles } from '../../types/bootstrapTypes';
interface UserInfoProps {
- user: User;
+ user: UserWithPermissionsAndRoles;
}
export default function UserInfo({ user }: UserInfoProps) {
diff --git a/superset-frontend/src/profile/types.ts b/superset-frontend/src/profile/types.ts
index 4e5a7eb..a2433e0 100644
--- a/superset-frontend/src/profile/types.ts
+++ b/superset-frontend/src/profile/types.ts
@@ -16,21 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-export type User = {
- createdOn: string;
- email: string;
- firstName: string;
- isActive: boolean;
- lastName: string;
- permissions: {
- database_access?: string[];
- datasource_access?: string[];
- };
- roles: Record<string, any>;
- userId: number;
- username: string;
-};
-
export type Slice = {
dttm: number;
id: number;
@@ -41,15 +26,6 @@ export type Slice = {
viz_type: string;
};
-export type Dashboard = {
- dttm: number;
- id: number;
- url: string;
- title: string;
- creator?: string;
- creator_url?: string;
-};
-
export type Activity = {
action: string;
item_title: string;
diff --git a/superset-frontend/src/profile/types.ts b/superset-frontend/src/types/bootstrapTypes.ts
similarity index 80%
copy from superset-frontend/src/profile/types.ts
copy to superset-frontend/src/types/bootstrapTypes.ts
index 4e5a7eb..cb8fb1e 100644
--- a/superset-frontend/src/profile/types.ts
+++ b/superset-frontend/src/types/bootstrapTypes.ts
@@ -22,24 +22,17 @@ export type User = {
firstName: string;
isActive: boolean;
lastName: string;
- permissions: {
- database_access?: string[];
- datasource_access?: string[];
- };
- roles: Record<string, any>;
userId: number;
username: string;
};
-export type Slice = {
- dttm: number;
- id: number;
- url: string;
- title: string;
- creator?: string;
- creator_url?: string;
- viz_type: string;
-};
+export interface UserWithPermissionsAndRoles extends User {
+ permissions: {
+ database_access?: string[];
+ datasource_access?: string[];
+ };
+ roles: Record<string, string[][]>;
+}
export type Dashboard = {
dttm: number;
@@ -49,10 +42,3 @@ export type Dashboard = {
creator?: string;
creator_url?: string;
};
-
-export type Activity = {
- action: string;
- item_title: string;
- item_url: string;
- time: number;
-};
diff --git a/superset-frontend/src/welcome/App.jsx b/superset-frontend/src/welcome/App.tsx
similarity index 97%
rename from superset-frontend/src/welcome/App.jsx
rename to superset-frontend/src/welcome/App.tsx
index 42e3f29..267dd5a 100644
--- a/superset-frontend/src/welcome/App.jsx
+++ b/superset-frontend/src/welcome/App.tsx
@@ -44,7 +44,7 @@ setupApp();
setupPlugins();
const container = document.getElementById('app');
-const bootstrap = JSON.parse(container.getAttribute('data-bootstrap'));
+const bootstrap = JSON.parse(container?.getAttribute('data-bootstrap') ?? '{}');
const user = { ...bootstrap.user };
const menu = { ...bootstrap.common.menu_data };
const common = { ...bootstrap.common };
diff --git a/superset-frontend/src/welcome/DashboardTable.jsx b/superset-frontend/src/welcome/DashboardTable.tsx
similarity index 80%
rename from superset-frontend/src/welcome/DashboardTable.jsx
rename to superset-frontend/src/welcome/DashboardTable.tsx
index 6399064..704cdc3 100644
--- a/superset-frontend/src/welcome/DashboardTable.jsx
+++ b/superset-frontend/src/welcome/DashboardTable.tsx
@@ -17,35 +17,45 @@
* under the License.
*/
import React from 'react';
-import PropTypes from 'prop-types';
import { t } from '@superset-ui/translation';
import { SupersetClient } from '@superset-ui/connection';
import moment from 'moment';
import { debounce } from 'lodash';
import ListView from 'src/components/ListView/ListView';
import withToasts from 'src/messageToasts/enhancers/withToasts';
+import { Dashboard } from 'src/types/bootstrapTypes';
+import { FetchDataConfig } from 'src/components/ListView/types';
const PAGE_SIZE = 25;
-class DashboardTable extends React.PureComponent {
- static propTypes = {
- addDangerToast: PropTypes.func.isRequired,
- search: PropTypes.string,
- };
+interface DashboardTableProps {
+ addDangerToast: (message: string) => void;
+ search?: string;
+}
+
+interface DashboardTableState {
+ dashboards: Dashboard[];
+ dashboard_count: number;
+ loading: boolean;
+}
+class DashboardTable extends React.PureComponent<
+ DashboardTableProps,
+ DashboardTableState
+> {
state = {
dashboards: [],
dashboard_count: 0,
loading: false,
};
- componentDidUpdate(prevProps) {
+ componentDidUpdate(prevProps: DashboardTableProps) {
if (prevProps.search !== this.props.search) {
this.fetchDataDebounced({
pageSize: PAGE_SIZE,
pageIndex: 0,
sortBy: this.initialSort,
- filters: {},
+ filters: [],
});
}
}
@@ -58,6 +68,13 @@ class DashboardTable extends React.PureComponent {
row: {
original: { url, dashboard_title: dashboardTitle },
},
+ }: {
+ row: {
+ original: {
+ url: string;
+ dashboard_title: string;
+ };
+ };
}) => <a href={url}>{dashboardTitle}</a>,
},
{
@@ -67,6 +84,13 @@ class DashboardTable extends React.PureComponent {
row: {
original: { changed_by_name: changedByName, changedByUrl },
},
+ }: {
+ row: {
+ original: {
+ changed_by_name: string;
+ changedByUrl: string;
+ };
+ };
}) => <a href={changedByUrl}>{changedByName}</a>,
},
{
@@ -76,13 +100,19 @@ class DashboardTable extends React.PureComponent {
row: {
original: { changed_on: changedOn },
},
+ }: {
+ row: {
+ original: {
+ changed_on: string;
+ };
+ };
}) => <span className="no-wrap">{moment(changedOn).fromNow()}</span>,
},
];
initialSort = [{ id: 'changed_on', desc: true }];
- fetchData = ({ pageIndex, pageSize, sortBy, filters }) => {
+ fetchData = ({ pageIndex, pageSize, sortBy, filters }: FetchDataConfig) => {
this.setState({ loading: true });
const filterExps = Object.keys(filters)
.map(fk => ({
diff --git a/superset-frontend/src/welcome/Welcome.jsx b/superset-frontend/src/welcome/Welcome.tsx
similarity index 83%
rename from superset-frontend/src/welcome/Welcome.jsx
rename to superset-frontend/src/welcome/Welcome.tsx
index 97d17f9..3ec66e1 100644
--- a/superset-frontend/src/welcome/Welcome.jsx
+++ b/superset-frontend/src/welcome/Welcome.tsx
@@ -17,23 +17,30 @@
* under the License.
*/
import React, { useState } from 'react';
-import PropTypes from 'prop-types';
import { Panel, Row, Col, Tabs, Tab, FormControl } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
-import { useQueryParam, StringParam } from 'use-query-params';
+import { useQueryParam, StringParam, QueryParamConfig } from 'use-query-params';
+import { User } from 'src/types/bootstrapTypes';
import RecentActivity from '../profile/components/RecentActivity';
import Favorites from '../profile/components/Favorites';
import DashboardTable from './DashboardTable';
-const propTypes = {
- user: PropTypes.object.isRequired,
-};
+interface WelcomeProps {
+ user: User;
+}
-function useSyncQueryState(queryParam, queryParamType, defaultState) {
+function useSyncQueryState(
+ queryParam: string,
+ queryParamType: QueryParamConfig<
+ string | null | undefined,
+ string | undefined
+ >,
+ defaultState: string,
+): [string, (val: string) => void] {
const [queryState, setQueryState] = useQueryParam(queryParam, queryParamType);
const [state, setState] = useState(queryState || defaultState);
- const setQueryStateAndState = val => {
+ const setQueryStateAndState = (val: string) => {
setQueryState(val);
setState(val);
};
@@ -41,7 +48,7 @@ function useSyncQueryState(queryParam, queryParamType, defaultState) {
return [state, setQueryStateAndState];
}
-export default function Welcome({ user }) {
+export default function Welcome({ user }: WelcomeProps) {
const [activeTab, setActiveTab] = useSyncQueryState(
'activeTab',
StringParam,
@@ -58,6 +65,7 @@ export default function Welcome({ user }) {
<div className="container welcome">
<Tabs
activeKey={activeTab}
+ // @ts-ignore React bootstrap types aren't quite right here
onSelect={setActiveTab}
id="uncontrolled-tab-example"
>
@@ -75,6 +83,7 @@ export default function Welcome({ user }) {
style={{ marginTop: '25px' }}
placeholder="Search"
value={searchQuery}
+ // @ts-ignore React bootstrap types aren't quite right here
onChange={e => setSearchQuery(e.currentTarget.value)}
/>
</Col>
@@ -114,5 +123,3 @@ export default function Welcome({ user }) {
</div>
);
}
-
-Welcome.propTypes = propTypes;
diff --git a/superset-frontend/src/welcome/index.jsx b/superset-frontend/src/welcome/index.tsx
similarity index 100%
rename from superset-frontend/src/welcome/index.jsx
rename to superset-frontend/src/welcome/index.tsx
diff --git a/superset-frontend/webpack.config.js b/superset-frontend/webpack.config.js
index 2d3545b..d6295d3 100644
--- a/superset-frontend/webpack.config.js
+++ b/superset-frontend/webpack.config.js
@@ -181,7 +181,7 @@ const config = {
explore: addPreamble('/src/explore/index.jsx'),
dashboard: addPreamble('/src/dashboard/index.jsx'),
sqllab: addPreamble('/src/SqlLab/index.tsx'),
- welcome: addPreamble('/src/welcome/index.jsx'),
+ welcome: addPreamble('/src/welcome/index.tsx'),
profile: addPreamble('/src/profile/index.tsx'),
showSavedQuery: [path.join(APP_DIR, '/src/showSavedQuery/index.jsx')],
},