feat(listview): set default view mode based on THUMBNAIL feature flag (#10691)

* feat(listview): set default view mode based on THUMBNAIL feature flag

* add spec

* better generic typing for ListView

* lint

* fix specs
This commit is contained in:
ʈᵃᵢ 2020-08-27 09:40:32 -07:00 committed by GitHub
parent bb92c1f84d
commit 81525c3e9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 63 additions and 13 deletions

View File

@ -292,13 +292,13 @@ describe('ListView', () => {
);
});
it('disable card view based on prop', async () => {
it('disables card view based on prop', async () => {
expect(wrapper.find(CardCollection).exists()).toBe(false);
expect(wrapper.find(CardSortSelect).exists()).toBe(false);
expect(wrapper.find(TableCollection).exists()).toBe(true);
});
it('enable card view based on prop', async () => {
it('enables card view based on prop', async () => {
const wrapper2 = factory({
...mockedProps,
renderCard: jest.fn(),
@ -310,6 +310,26 @@ describe('ListView', () => {
expect(wrapper2.find(TableCollection).exists()).toBe(false);
});
it('allows setting the default view mode', async () => {
const wrapper2 = factory({
...mockedProps,
renderCard: jest.fn(),
defaultViewMode: 'card',
initialSort: [{ id: 'something' }],
});
await waitForComponentToPaint(wrapper2);
expect(wrapper2.find(CardCollection).exists()).toBe(true);
const wrapper3 = factory({
...mockedProps,
renderCard: jest.fn(),
defaultViewMode: 'table',
initialSort: [{ id: 'something' }],
});
await waitForComponentToPaint(wrapper3);
expect(wrapper3.find(TableCollection).exists()).toBe(true);
});
it('Throws an exception if filter missing in columns', () => {
expect.assertions(1);
const props = {

View File

@ -20,6 +20,7 @@ import React from 'react';
import thunk from 'redux-thunk';
import configureStore from 'redux-mock-store';
import fetchMock from 'fetch-mock';
import * as featureFlags from 'src/featureFlags';
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
import { styledMount as mount } from 'spec/helpers/theming';
@ -75,6 +76,13 @@ global.URL.createObjectURL = jest.fn();
fetchMock.get('/thumbnail', { body: new Blob(), sendAsJson: false });
describe('ChartList', () => {
const isFeatureEnabledMock = jest
.spyOn(featureFlags, 'isFeatureEnabled')
.mockImplementation(feature => feature === 'THUMBNAILS');
afterAll(() => {
isFeatureEnabledMock.restore();
});
const mockedProps = {};
const wrapper = mount(<ChartList {...mockedProps} />, {
context: { store },

View File

@ -20,6 +20,7 @@ import React from 'react';
import thunk from 'redux-thunk';
import configureStore from 'redux-mock-store';
import fetchMock from 'fetch-mock';
import * as featureFlags from 'src/featureFlags';
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
import { styledMount as mount } from 'spec/helpers/theming';
@ -67,6 +68,14 @@ global.URL.createObjectURL = jest.fn();
fetchMock.get('/thumbnail', { body: new Blob(), sendAsJson: false });
describe('DashboardList', () => {
const isFeatureEnabledMock = jest
.spyOn(featureFlags, 'isFeatureEnabled')
.mockImplementation(feature => feature === 'THUMBNAILS');
afterAll(() => {
isFeatureEnabledMock.restore();
});
const mockedProps = {};
const wrapper = mount(<DashboardList {...mockedProps} />, {
context: { store },

View File

@ -17,7 +17,7 @@
* under the License.
*/
import { t } from '@superset-ui/translation';
import React, { FunctionComponent, useState } from 'react';
import React, { useState } from 'react';
import { Alert } from 'react-bootstrap';
import styled from '@superset-ui/style';
import cx from 'classnames';
@ -174,7 +174,9 @@ const ViewModeToggle = ({
</ViewModeContainer>
);
};
export interface ListViewProps<T = any> {
type ViewModeType = 'card' | 'table';
export interface ListViewProps<T extends object = any> {
columns: any[];
data: T[];
count: number;
@ -193,11 +195,12 @@ export interface ListViewProps<T = any> {
bulkSelectEnabled?: boolean;
disableBulkSelect?: () => void;
renderBulkSelectCopy?: (selects: any[]) => React.ReactNode;
renderCard?: (row: T) => React.ReactNode;
renderCard?: (row: T & { loading: boolean }) => React.ReactNode;
cardSortSelectOptions?: Array<CardSortSelectOption>;
defaultViewMode?: ViewModeType;
}
const ListView: FunctionComponent<ListViewProps> = ({
function ListView<T extends object = any>({
columns,
data,
count,
@ -213,7 +216,8 @@ const ListView: FunctionComponent<ListViewProps> = ({
renderBulkSelectCopy = selected => t('%s Selected', selected.length),
renderCard,
cardSortSelectOptions,
}) => {
defaultViewMode = 'card',
}: ListViewProps<T>) {
const {
getTableProps,
getTableBodyProps,
@ -253,8 +257,8 @@ const ListView: FunctionComponent<ListViewProps> = ({
}
const cardViewEnabled = Boolean(renderCard);
const [viewingMode, setViewingMode] = useState<'table' | 'card'>(
cardViewEnabled ? 'card' : 'table',
const [viewingMode, setViewingMode] = useState<ViewModeType>(
cardViewEnabled ? defaultViewMode : 'table',
);
return (
@ -365,6 +369,6 @@ const ListView: FunctionComponent<ListViewProps> = ({
</div>
</ListViewStyles>
);
};
}
export default ListView;

View File

@ -26,6 +26,7 @@ export enum FeatureFlag {
ESTIMATE_QUERY_COST = 'ESTIMATE_QUERY_COST',
SHARE_QUERIES_VIA_KV_STORE = 'SHARE_QUERIES_VIA_KV_STORE',
SQLLAB_BACKEND_PERSISTENCE = 'SQLLAB_BACKEND_PERSISTENCE',
THUMBNAILS = 'THUMBNAILS',
}
export type FeatureFlagMap = {

View File

@ -22,6 +22,7 @@ import { getChartMetadataRegistry } from '@superset-ui/chart';
import React, { useState, useMemo } from 'react';
import rison from 'rison';
import { uniqBy } from 'lodash';
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
import { createFetchRelated, createErrorHandler } from 'src/views/CRUD/utils';
import { useListViewResource, useFavoriteStatus } from 'src/views/CRUD/hooks';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
@ -502,7 +503,7 @@ function ChartList(props: ChartListProps) {
: [];
return (
<ListView
<ListView<Chart>
bulkActions={bulkActions}
bulkSelectEnabled={bulkSelectEnabled}
cardSortSelectOptions={sortTypes}
@ -517,6 +518,9 @@ function ChartList(props: ChartListProps) {
loading={loading}
pageSize={PAGE_SIZE}
renderCard={renderCard}
defaultViewMode={
isFeatureEnabled(FeatureFlag.THUMBNAILS) ? 'card' : 'table'
}
/>
);
}}

View File

@ -20,6 +20,7 @@ import { SupersetClient } from '@superset-ui/connection';
import { t } from '@superset-ui/translation';
import React, { useState, useMemo } from 'react';
import rison from 'rison';
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
import { createFetchRelated, createErrorHandler } from 'src/views/CRUD/utils';
import { useListViewResource, useFavoriteStatus } from 'src/views/CRUD/hooks';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
@ -510,7 +511,7 @@ function DashboardList(props: DashboardListProps) {
onSubmit={handleDashboardEdit}
/>
)}
<ListView
<ListView<Dashboard>
bulkActions={bulkActions}
bulkSelectEnabled={bulkSelectEnabled}
cardSortSelectOptions={sortTypes}
@ -525,6 +526,9 @@ function DashboardList(props: DashboardListProps) {
loading={loading}
pageSize={PAGE_SIZE}
renderCard={renderCard}
defaultViewMode={
isFeatureEnabled(FeatureFlag.THUMBNAILS) ? 'card' : 'table'
}
/>
</>
);

View File

@ -540,7 +540,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
: [];
return (
<ListView
<ListView<Dataset>
className="dataset-list-view"
columns={columns}
data={datasets}