Skip to content
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

feat: View all fav charts and dashboards #12060

Merged
merged 13 commits into from
Dec 18, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('SavedQueries', () => {
expect(wrapper.find(SavedQueries)).toExist();
});

it('fetches queries favorites and renders listviewcard cards', async () => {
it('fetches queries mine and renders listviewcard cards', async () => {
clickTab(0);
await waitForComponentToPaint(wrapper);
expect(fetchMock.calls(/saved_query\/\?q/)).toHaveLength(1);
Expand All @@ -105,9 +105,9 @@ describe('SavedQueries', () => {

it('it renders a submenu with clickable tables and buttons', async () => {
expect(wrapper.find(SubMenu)).toExist();
expect(wrapper.find('li')).toHaveLength(2);
expect(wrapper.find('li')).toHaveLength(1);
expect(wrapper.find('button')).toHaveLength(2);
clickTab(1);
clickTab(0);
await waitForComponentToPaint(wrapper);
expect(fetchMock.calls(/saved_query\/\?q/)).toHaveLength(2);
});
Expand Down
8 changes: 7 additions & 1 deletion superset-frontend/src/components/ListView/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,14 @@ type FilterOperator =
| 'all_text'
| 'chart_all_text'
| 'dataset_is_null_or_empty'
| 'between';
| 'between'
| 'dashboard_is_fav'
| 'chart_is_fav';
geido marked this conversation as resolved.
Show resolved Hide resolved

export interface Filter {
Header: ReactNode;
id: string;
urlDisplay?: string;
operator?: FilterOperator;
input?:
| 'text'
Expand All @@ -85,6 +88,7 @@ export type ViewModeType = 'card' | 'table';

export interface FilterValue {
id: string;
urlDisplay?: string;
operator?: string;
value: string | boolean | number | null | undefined | string[] | number[];
}
Expand Down Expand Up @@ -119,4 +123,6 @@ export enum FilterOperators {
chartAllText = 'chart_all_text',
datasetIsNullOrEmpty = 'dataset_is_null_or_empty',
between = 'between',
dashboardIsFav = 'dashboard_is_fav',
chartIsFav = 'chart_is_fav',
}
17 changes: 12 additions & 5 deletions superset-frontend/src/components/ListView/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ type QueryFilterState = {
};

function mergeCreateFilterValues(list: Filter[], updateObj: QueryFilterState) {
return list.map(({ id, operator }) => {
const update = updateObj[id];
return list.map(({ id, urlDisplay, operator }) => {
const currentFilterId = urlDisplay || id;
const update = updateObj[currentFilterId];

return { id, operator, value: update };
return { id, urlDisplay, operator, value: update };
});
}

Expand Down Expand Up @@ -143,10 +144,12 @@ export function convertFiltersRison(

// Add operators from filter list
list.forEach(value => {
const filter = refs[value.id];
const currentFilterId = value.urlDisplay || value.id;
const filter = refs[currentFilterId];

if (filter) {
filter.operator = value.operator;
filter.id = value.id;
}
});

Expand Down Expand Up @@ -294,7 +297,8 @@ export function useListViewState({
filter.value !== undefined &&
(typeof filter.value !== 'string' || filter.value.length > 0)
) {
filterObj[filter.id] = filter.value;
const currentFilterId = filter.urlDisplay || filter.id;
filterObj[currentFilterId] = filter.value;
}
});

Expand All @@ -318,6 +322,7 @@ export function useListViewState({
: 'replace';

setQuery(queryParams, method);

fetchData({ pageIndex, pageSize, sortBy, filters });
}, [fetchData, pageIndex, pageSize, sortBy, filters, viewMode]);

Expand All @@ -333,12 +338,14 @@ export function useListViewState({
if (currentInternalFilters[index].value === value) {
return currentInternalFilters;
}

const update = { ...currentInternalFilters[index], value };
const updatedFilters = updateInList(
currentInternalFilters,
index,
update,
);

setAllFilters(convertFilters(updatedFilters));
gotoPage(0); // clear pagination on filter
return updatedFilters;
Expand Down
25 changes: 19 additions & 6 deletions superset-frontend/src/views/CRUD/chart/ChartList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import ListView, {
ListViewProps,
Filters,
SelectOption,
FilterOperators,
} from 'src/components/ListView';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import PropertiesModal from 'src/explore/components/PropertiesModal';
Expand Down Expand Up @@ -195,7 +196,7 @@ function ChartList(props: ChartListProps) {
/>
),
Header: '',
id: 'favorite',
id: 'id',
disableSortBy: true,
size: 'xs',
},
Expand Down Expand Up @@ -367,7 +368,7 @@ function ChartList(props: ChartListProps) {
Header: t('Owner'),
id: 'owners',
input: 'select',
operator: 'rel_m_m',
operator: FilterOperators.relationManyMany,
unfilteredLabel: 'All',
fetchSelects: createFetchRelated(
'chart',
Expand All @@ -388,7 +389,7 @@ function ChartList(props: ChartListProps) {
Header: t('Created By'),
id: 'created_by',
input: 'select',
operator: 'rel_o_m',
operator: FilterOperators.relationOneMany,
unfilteredLabel: 'All',
fetchSelects: createFetchRelated(
'chart',
Expand All @@ -409,7 +410,7 @@ function ChartList(props: ChartListProps) {
Header: t('Viz Type'),
id: 'viz_type',
input: 'select',
operator: 'eq',
operator: FilterOperators.equals,
unfilteredLabel: 'All',
selects: getChartMetadataRegistry()
.keys()
Expand All @@ -433,7 +434,7 @@ function ChartList(props: ChartListProps) {
Header: t('Dataset'),
id: 'datasource_id',
input: 'select',
operator: 'eq',
operator: FilterOperators.equals,
unfilteredLabel: 'All',
fetchSelects: createFetchDatasets(
createErrorHandler(errMsg =>
Expand All @@ -447,11 +448,23 @@ function ChartList(props: ChartListProps) {
),
paginate: false,
},
{
Header: t('Favorite'),
id: 'id',
urlDisplay: 'favorite',
input: 'select',
operator: FilterOperators.chartIsFav,
unfilteredLabel: 'Any',
selects: [
{ label: t('Yes'), value: true },
{ label: t('No'), value: false },
],
},
{
Header: t('Search'),
id: 'slice_name',
input: 'search',
operator: 'chart_all_text',
operator: FilterOperators.chartAllText,
},
];

Expand Down
29 changes: 23 additions & 6 deletions superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ import {
import { useListViewResource, useFavoriteStatus } from 'src/views/CRUD/hooks';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
import ListView, { ListViewProps, Filters } from 'src/components/ListView';
import ListView, {
ListViewProps,
Filters,
FilterOperators,
} from 'src/components/ListView';
import Owner from 'src/types/Owner';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import FacePile from 'src/components/FacePile';
Expand Down Expand Up @@ -104,6 +108,7 @@ function DashboardList(props: DashboardListProps) {
dashboardIds,
addDangerToast,
);

const [dashboardToEdit, setDashboardToEdit] = useState<Dashboard | null>(
null,
);
Expand Down Expand Up @@ -189,7 +194,7 @@ function DashboardList(props: DashboardListProps) {
/>
),
Header: '',
id: 'favorite',
id: 'id',
disableSortBy: true,
size: 'xs',
},
Expand Down Expand Up @@ -354,7 +359,7 @@ function DashboardList(props: DashboardListProps) {
Header: t('Owner'),
id: 'owners',
input: 'select',
operator: 'rel_m_m',
operator: FilterOperators.relationManyMany,
unfilteredLabel: 'All',
fetchSelects: createFetchRelated(
'dashboard',
Expand All @@ -375,7 +380,7 @@ function DashboardList(props: DashboardListProps) {
Header: t('Created By'),
id: 'created_by',
input: 'select',
operator: 'rel_o_m',
operator: FilterOperators.relationOneMany,
unfilteredLabel: 'All',
fetchSelects: createFetchRelated(
'dashboard',
Expand All @@ -396,18 +401,30 @@ function DashboardList(props: DashboardListProps) {
Header: t('Status'),
id: 'published',
input: 'select',
operator: 'eq',
operator: FilterOperators.equals,
unfilteredLabel: 'Any',
selects: [
{ label: t('Published'), value: true },
{ label: t('Unpublished'), value: false },
],
},
{
Header: t('Favorite'),
id: 'id',
urlDisplay: 'favorite',
input: 'select',
operator: FilterOperators.dashboardIsFav,
unfilteredLabel: 'Any',
selects: [
{ label: t('Yes'), value: true },
{ label: t('No'), value: false },
],
},
{
Header: t('Search'),
id: 'dashboard_title',
input: 'search',
operator: 'title_or_slug',
operator: FilterOperators.titleOrSlug,
},
];

Expand Down
4 changes: 2 additions & 2 deletions superset-frontend/src/views/CRUD/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ export function useListViewResource<D extends object = any>(

const filterExps = baseFilters
.concat(filterValues)
.map(({ id: col, operator: opr, value }) => ({
col,
.map(({ id, operator: opr, value }) => ({
col: id,
opr,
value,
}));
Expand Down
10 changes: 8 additions & 2 deletions superset-frontend/src/views/CRUD/welcome/ChartTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
useFavoriteStatus,
} from 'src/views/CRUD/hooks';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import { useHistory } from 'react-router-dom';
import PropertiesModal from 'src/explore/components/PropertiesModal';
import { User } from 'src/types/bootstrapTypes';
import Icon from 'src/components/Icon';
Expand All @@ -50,6 +51,7 @@ function ChartTable({
addSuccessToast,
mine,
}: ChartTableProps) {
const history = useHistory();
const {
state: { resourceCollection: charts, bulkSelectEnabled },
setResourceCollection: setCharts,
Expand Down Expand Up @@ -148,14 +150,18 @@ function ChartTable({
),
buttonStyle: 'tertiary',
onClick: () => {
window.location.href = '/chart/add';
history.push('/chart/add');
},
},
{
name: 'View All »',
buttonStyle: 'link',
onClick: () => {
window.location.href = '/chart/list';
const target =
chartFilter === 'Favorite'
? '/chart/list/?filters=(favorite:!t)'
: '/chart/list/';
history.push(target);
},
},
]}
Expand Down
10 changes: 8 additions & 2 deletions superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import React, { useState, useMemo } from 'react';
import { SupersetClient, t } from '@superset-ui/core';
import { useListViewResource, useFavoriteStatus } from 'src/views/CRUD/hooks';
import { Dashboard, DashboardTableProps } from 'src/views/CRUD/types';
import { useHistory } from 'react-router-dom';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import PropertiesModal from 'src/dashboard/components/PropertiesModal';
import DashboardCard from 'src/views/CRUD/dashboard/DashboardCard';
Expand All @@ -42,6 +43,7 @@ function DashboardTable({
addSuccessToast,
mine,
}: DashboardTableProps) {
const history = useHistory();
const {
state: { loading, resourceCollection: dashboards },
setResourceCollection: setDashboards,
Expand Down Expand Up @@ -155,14 +157,18 @@ function DashboardTable({
),
buttonStyle: 'tertiary',
onClick: () => {
window.location.href = '/dashboard/new';
history.push('/dashboard/new');
},
},
{
name: 'View All »',
buttonStyle: 'link',
onClick: () => {
window.location.href = '/dashboard/list/';
const target =
dashboardFilter === 'Favorite'
? '/dashboard/list/?filters=(favorite:!t)'
: '/dashboard/list/';
history.push(target);
},
},
]}
Expand Down
2 changes: 2 additions & 0 deletions superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,15 @@ const SavedQueries = ({
<SubMenu
activeChild={queryFilter}
tabs={[
/* @TODO uncomment when fav functionality is implemented
{
name: 'Favorite',
label: t('Favorite'),
onClick: () => {
getData('Favorite').then(() => setQueryFilter('Favorite'));
},
},
*/
{
name: 'Mine',
label: t('Mine'),
Expand Down