This is an automated email from the ASF dual-hosted git repository. yjc pushed a commit to branch home-screen-mvp in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
commit fbd15110d25c5c1b41ffee33ae3d307bf3ba2796 Author: Phillip Kelley-Dotson <[email protected]> AuthorDate: Thu Oct 1 19:52:23 2020 -0700 more updates --- .../src/components/ListViewCard/index.tsx | 2 +- superset-frontend/src/components/Menu/SubMenu.tsx | 5 - .../src/views/CRUD/dashboard/DashboardCard.tsx | 2 +- .../src/views/CRUD/welcome/ActivityTable.tsx | 123 +++++++++++++++++++++ .../src/views/CRUD/welcome/DashboardTable.tsx | 29 +---- .../src/views/CRUD/welcome/SavedQueries.tsx | 33 +++--- .../src/views/CRUD/welcome/Welcome.tsx | 42 +++++-- superset/views/api.py | 2 - 8 files changed, 181 insertions(+), 57 deletions(-) diff --git a/superset-frontend/src/components/ListViewCard/index.tsx b/superset-frontend/src/components/ListViewCard/index.tsx index f07970c..fc62f7b 100644 --- a/superset-frontend/src/components/ListViewCard/index.tsx +++ b/superset-frontend/src/components/ListViewCard/index.tsx @@ -152,7 +152,7 @@ interface CardProps { coverLeft?: React.ReactNode; coverRight?: React.ReactNode; actions: React.ReactNode; - showImg: boolean; + showImg?: boolean; rows?: number | string; } diff --git a/superset-frontend/src/components/Menu/SubMenu.tsx b/superset-frontend/src/components/Menu/SubMenu.tsx index 381ac2e..df7e501 100644 --- a/superset-frontend/src/components/Menu/SubMenu.tsx +++ b/superset-frontend/src/components/Menu/SubMenu.tsx @@ -66,13 +66,8 @@ type MenuClickHandler = React.MouseEventHandler<MenuItem>; type MenuChild = { label: string; name: string; -<<<<<<< HEAD url: string; usesRouter?: boolean; -======= - url?: string; - onClick?: any; ->>>>>>> step 1: broken stuff! }; export interface ButtonProps { diff --git a/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx b/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx index 46d3088..f42de20 100644 --- a/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx +++ b/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx @@ -21,7 +21,7 @@ interface Dashboard { changed_on_delta_humanized: string; changed_by: string; dashboard_title: string; - slice_name: string; + slice_name?: string; id: number; published: boolean; url: string; diff --git a/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx b/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx new file mode 100644 index 0000000..9203848 --- /dev/null +++ b/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx @@ -0,0 +1,123 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { useEffect, useState } from 'react'; +import { styled, SupersetClient, t } from '@superset-ui/core'; +import rison from 'rison'; +import moment from 'moment'; +import { addDangerToast } from 'src/messageToasts/actions'; +import { createBatchMethod, createErrorHandler } from '../utils'; + +interface MapProps { + item_title: string; + slice_name: string; + time: string; + changed_on_utc: string; + user: { + userId: string | number; + }; + activityFilter: string; + item_url: string; +} + +const Cards = styled.div` + width: 200px; + padding: 15px; + border: 1px solid #f0f0f0; +`; + +const filters = { + // Chart and dashbaord uses same filters + // for edited and created + edited: [ + { + col: 'changed_by', + opr: 'rel_o_m', + value: 1, + }, + ], + created: [ + { + col: 'owners', + opr: 'rel_m_m', + value: 1, + }, + ], +}; + +export default function ActivityTable({ user, activityFilter }: MapProps) { + const [active, setActiveState] = useState([]); + const recent = `/superset/recent_activity/${user.userId}/?limit=10`; + const setData = (endpoint: string) => { + SupersetClient.get(endpoint) + .then(({ json }) => { + setActiveState(json); + }) + .catch(e => { + createErrorHandler(err => + addDangerToast(t('There was an issue fetching your resource')), + ); + }); + }; + + const setBatchData = (q: string) => { + createBatchMethod(q).then((res: Array<object>) => { + setActiveState(res); + }); + }; + + const getData = () => { + const queryParams = rison.encode({ + order_column: 'changed_on_delta_humanized', + order_direction: 'desc', + page: 0, + page_size: 0, + filters: activityFilter !== 'Created' ? filters.edited : filters.created, + }); + if (activityFilter === 'Viewed') { + setData({ endpoint: recent }); + } + if (activityFilter === 'Edited') { + setBatchData(queryParams); + } + if (activityFilter === 'Created') { + setBatchData(queryParams); + } + }; + + useEffect(() => { + getData(); + }, [activityFilter]); + + const renderActivity = () => { + return active.map((e: MapProps) => ( + <a href={e.item_url}> + <Cards> + <div>{activityFilter === 'Viewed' ? e.item_title : e.slice_name}</div> + <div> + {moment + .utc(activityFilter === 'Viewd' ? e.time : e.changed_on_utc) + .fromNow()} + </div> + </Cards> + </a> + )); + }; + + return <> {renderActivity()} </>; +} diff --git a/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx b/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx index 39c5503..ca3f584 100644 --- a/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx +++ b/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx @@ -17,24 +17,14 @@ * under the License. */ import React, { useEffect } from 'react'; -import { t } from '@superset-ui/core'; -import { debounce } from 'lodash'; -import ListView, { FetchDataConfig } from 'src/components/ListView'; +import { t, styled } from '@superset-ui/core'; import { useListViewResource, useFavoriteStatus } from 'src/views/CRUD/hooks'; import withToasts from 'src/messageToasts/enhancers/withToasts'; import { User } from 'src/types/bootstrapTypes'; -import ListViewCard from 'src/components/ListViewCard'; -import { Dropdown, Menu } from 'src/common/components'; -import Icon from 'src/components/Icon'; -import Label from 'src/components/Label'; import Owner from 'src/types/Owner'; -import ConfirmStatusChange from 'src/components/ConfirmStatusChange'; import DashboardCard from '../dashboard/DashboardCard'; -const PAGE_SIZE = 3; -// const canEdit = hasPerm('can_edit'); -// const canDelete = hasPerm('can_delete'); -// const canExport = hasPerm('can_mulexport'); +const PAGE_SIZE = 3; interface DashboardTableProps { addDangerToast: (message: string) => void; @@ -58,22 +48,12 @@ interface Dashboard { loading: boolean; } -interface DashboardTableState { - dashboards: Dashboard[]; - dashboard_count: number; - loading: boolean; -} - export interface FilterValue { col: string; operator: string; value: string | boolean | number | null | undefined; } -export interface FetchDataConfig { - filters: FilterValue[]; -} - function DashboardTable({ dashboardFilter, user, @@ -91,7 +71,6 @@ function DashboardTable({ t('dashboard'), addDangerToast, ); - console.log('dashboardFilter', dashboardFilter); const getFilters = () => { const filters = []; @@ -133,7 +112,7 @@ function DashboardTable({ }, [dashboardFilter]); return ( - <div> + <> {dashboards.map(e => ( <DashboardCard {...{ @@ -146,7 +125,7 @@ function DashboardTable({ }} /> ))} - </div> + </> ); } diff --git a/superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx b/superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx index 7f261cc..116cf91 100644 --- a/superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx +++ b/superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx @@ -18,12 +18,18 @@ */ import React from 'react'; import { t, SupersetClient } from '@superset-ui/core'; -import { debounce } from 'lodash'; -import withToasts from 'src/messageToasts/enhancers/withToasts'; +// import withToasts from 'src/messageToasts/enhancers/withToasts'; +import { Dropdown } from 'src/common/components'; import ListViewCard from 'src/components/ListViewCard'; +// import FaveStar from 'src/components/FaveStar'; +import Icon from 'src/components/Icon'; + +interface StateProps { + queries: Array<object>; +} class SavedQueries extends React.PureComponent { - constructor(props: Readonly<{}>) { + constructor(props: StateProps) { super(props); this.state = { queries: [], @@ -32,28 +38,20 @@ class SavedQueries extends React.PureComponent { componentDidMount() { this.fetchData(); } + // eslint-disable-next-line consistent-return fetchData = async () => { try { - const ids = []; const { json } = await SupersetClient.get({ endpoint: `/api/v1/query/`, }); - /*(json.ids.forEach(id => { - const { json } = SupersetClient.get({ - endpoint: `/api/v1/query/${id}`, - }); - console.log('data', json); - });*/ - console.log('json.result', json); this.setState({ queries: json.result }); } catch (e) { return console.log(e); } }; render() { - console.log('q', this.state.queries) return ( - <div> + <> {this.state.queries.map(q => ( <ListViewCard title={q.database.database_name} @@ -61,9 +59,16 @@ class SavedQueries extends React.PureComponent { loading={false} description={t('Last run ', q.end_time)} showImg={false} + actions={ + <ListViewCard.Actions> + <Dropdown> + <Icon name="more" /> + </Dropdown> + </ListViewCard.Actions> + } /> ))} - </div> + </> ); } } diff --git a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx index a610d43..5b05075 100644 --- a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx +++ b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx @@ -19,8 +19,8 @@ import React, { useState } from 'react'; import { FormControl } from 'react-bootstrap'; import SubMenu from 'src/components/Menu/SubMenu'; +import { styled, t } from '@superset-ui/core'; import { Collapse } from 'src/common/components'; -import { t } from '@superset-ui/core'; import { useQueryParam, StringParam, QueryParamConfig } from 'use-query-params'; import { User } from 'src/types/bootstrapTypes'; import RecentActivity from 'src/profile/components/RecentActivity'; @@ -34,6 +34,24 @@ interface WelcomeProps { user: User; } +const ActivityContainer = styled.div` + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, max-content)); + grid-gap: ${({ theme }) => theme.gridUnit * 8}px; + justify-content: center; + padding: ${({ theme }) => theme.gridUnit * 2}px + ${({ theme }) => theme.gridUnit * 4}px; +`; + +export const CardContainer = styled.div` + display: grid; + grid-template-columns: repeat(auto-fit, minmax(459px, max-content)); + grid-gap: ${({ theme }) => theme.gridUnit * 8}px; + justify-content: center; + padding: ${({ theme }) => theme.gridUnit * 2}px + ${({ theme }) => theme.gridUnit * 4}px; +`; + function useSyncQueryState( queryParam: string, queryParamType: QueryParamConfig< @@ -75,7 +93,7 @@ export default function Welcome({ user }: WelcomeProps) { <Collapse defaultActiveKey={['1']}> <Panel header={t('Recents')} key="1"> <SubMenu - activeChild="Viewed" + activeChild={activtyFilter} name="" // eslint-disable-next-line react/no-children-prop children={[ @@ -96,7 +114,9 @@ export default function Welcome({ user }: WelcomeProps) { }, ]} /> - <RecentActivity user={user} /> + <ActivityContainer> + <ActivityTable user={user} activityFilter={activtyFilter} /> + </ActivityContainer> </Panel> <Panel header={t('Dashboards')} key="2"> @@ -125,11 +145,13 @@ export default function Welcome({ user }: WelcomeProps) { // @ts-ignore React bootstrap types aren't quite right here onChange={e => setSearchQuery(e.currentTarget.value)} /> - <DashboardTable - search={searchQuery} - dashboardFilter={dashboardFilter} - user={user} - /> + <CardContainer> + <DashboardTable + search={searchQuery} + dashboardFilter={dashboardFilter} + user={user} + /> + </CardContainer> </Panel> <Panel header={t('Saved Queries')} key="3"> @@ -150,7 +172,9 @@ export default function Welcome({ user }: WelcomeProps) { }, ]} /> - <SavedQueries /> + <CardContainer> + <SavedQueries /> + </CardContainer> </Panel> <Panel header={t('Charts')} key="4"> <SubMenu diff --git a/superset/views/api.py b/superset/views/api.py index 19686a6..a5090b3 100644 --- a/superset/views/api.py +++ b/superset/views/api.py @@ -42,11 +42,9 @@ class Api(BaseSupersetView): raises SupersetSecurityException: If the user cannot access the resource """ - print("hello") query_context = QueryContext(**json.loads(request.form["query_context"])) query_context.raise_for_access() payload_json = query_context.get_payload() - print("playload", payload_json) return json.dumps( payload_json, default=utils.json_int_dttm_ser, ignore_nan=True )
