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:
parent
bb92c1f84d
commit
81525c3e9d
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
|||
: [];
|
||||
|
||||
return (
|
||||
<ListView
|
||||
<ListView<Dataset>
|
||||
className="dataset-list-view"
|
||||
columns={columns}
|
||||
data={datasets}
|
||||
|
|
|
|||
Loading…
Reference in New Issue