Skip to content

Commit

Permalink
fix(datasets): consistent dataset list (apache#15014)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaoyongjie committed Jun 10, 2021
1 parent e409b07 commit 561ce9e
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 63 deletions.
Expand Up @@ -48,7 +48,7 @@ const datasourceData = {
};

const DATASOURCES_ENDPOINT =
'glob:*/api/v1/dataset/?q=(order_column:changed_on_delta_humanized,order_direction:asc,page:0,page_size:20)';
'glob:*/api/v1/dataset/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:25)';
const DATASOURCE_ENDPOINT = `glob:*/datasource/get/${datasourceData.type}/${datasourceData.id}`;
const DATASOURCE_PAYLOAD = { new: 'data' };

Expand Down
47 changes: 39 additions & 8 deletions superset-frontend/src/components/TableView/TableView.tsx
Expand Up @@ -16,12 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import React, { useEffect } from 'react';
import isEqual from 'lodash/isEqual';
import { styled, t } from '@superset-ui/core';
import { useFilters, usePagination, useSortBy, useTable } from 'react-table';
import { Empty } from 'src/common/components';
import { TableCollection, Pagination } from 'src/components/dataViewCommon';
import { SortColumns } from './types';
import { SortByType, ServerPagination } from './types';

const DEFAULT_PAGE_SIZE = 10;

Expand All @@ -34,8 +35,11 @@ export interface TableViewProps {
columns: any[];
data: any[];
pageSize?: number;
totalCount?: number;
serverPagination?: boolean;
onServerPagination?: (args: ServerPagination) => void;
initialPageIndex?: number;
initialSortBy?: SortColumns;
initialSortBy?: SortByType;
loading?: boolean;
withPagination?: boolean;
emptyWrapperType?: EmptyWrapperType;
Expand All @@ -57,13 +61,17 @@ const TableViewStyles = styled.div<{
${({ scrollTable, theme }) =>
scrollTable &&
`
height: 300px;
height: 380px;
margin-bottom: ${theme.gridUnit * 4}px;
overflow: auto;
`}
.table-cell.table-cell {
vertical-align: top;
.table-row {
height: 43px;
}
th[role='columnheader'] {
z-index: 1;
}
.pagination-container {
Expand Down Expand Up @@ -92,13 +100,16 @@ const TableView = ({
columns,
data,
pageSize: initialPageSize,
totalCount = data.length,
initialPageIndex,
initialSortBy = [],
loading = false,
withPagination = true,
emptyWrapperType = EmptyWrapperType.Default,
noDataText,
showRowCount = true,
serverPagination = false,
onServerPagination = () => {},
...props
}: TableViewProps) => {
const initialState = {
Expand All @@ -116,18 +127,38 @@ const TableView = ({
prepareRow,
pageCount,
gotoPage,
state: { pageIndex, pageSize },
state: { pageIndex, pageSize, sortBy },
} = useTable(
{
columns,
data,
initialState,
manualPagination: serverPagination,
manualSortBy: serverPagination,
pageCount: Math.ceil(totalCount / initialState.pageSize),
},
useFilters,
useSortBy,
usePagination,
);

useEffect(() => {
if (serverPagination && pageIndex !== initialState.pageIndex) {
onServerPagination({
pageIndex,
});
}
}, [pageIndex]);

useEffect(() => {
if (serverPagination && !isEqual(sortBy, initialState.sortBy)) {
onServerPagination({
pageIndex: 0,
sortBy,
});
}
}, [sortBy]);

const content = withPagination ? page : rows;

let EmptyWrapperComponent;
Expand Down Expand Up @@ -182,7 +213,7 @@ const TableView = ({
'%s-%s of %s',
pageSize * pageIndex + (page.length && 1),
pageSize * pageIndex + page.length,
data.length,
totalCount,
)}
</div>
)}
Expand Down
12 changes: 7 additions & 5 deletions superset-frontend/src/components/TableView/types.ts
Expand Up @@ -16,9 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
export interface SortColumn {
id: string;
desc?: boolean;
}
import { SortingRule } from 'react-table';

export type SortByType = SortingRule<string>[];

export type SortColumns = SortColumn[];
export interface ServerPagination {
pageIndex: number;
sortBy?: SortByType;
}
104 changes: 70 additions & 34 deletions superset-frontend/src/datasource/ChangeDatasourceModal.tsx
Expand Up @@ -26,15 +26,22 @@ import React, {
import Alert from 'src/components/Alert';
import { SupersetClient, t, styled } from '@superset-ui/core';
import TableView, { EmptyWrapperType } from 'src/components/TableView';
import { ServerPagination, SortByType } from 'src/components/TableView/types';
import StyledModal from 'src/components/Modal';
import Button from 'src/components/Button';
import { useListViewResource } from 'src/views/CRUD/hooks';
import Dataset from 'src/types/Dataset';
import { useDebouncedEffect } from 'src/explore/exploreUtils';
import { SLOW_DEBOUNCE } from 'src/constants';
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
import Loading from 'src/components/Loading';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import { Input, AntdInput } from 'src/common/components';
import {
PAGE_SIZE as DATASET_PAGE_SIZE,
SORT_BY as DATASET_SORT_BY,
} from 'src/views/CRUD/data/dataset/constants';
import FacePile from '../components/FacePile';

const CONFIRM_WARNING_MESSAGE = t(
'Warning! Changing the dataset may break the chart if the metadata does not exist.',
Expand Down Expand Up @@ -81,21 +88,6 @@ const StyledSpan = styled.span`
}
`;

const TABLE_COLUMNS = [
'name',
'type',
'schema',
'connection',
'creator',
].map(col => ({ accessor: col, Header: col }));

const emptyRequest = {
pageIndex: 0,
pageSize: 20,
filters: [],
sortBy: [{ id: 'changed_on_delta_humanized' }],
};

const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
addDangerToast,
addSuccessToast,
Expand All @@ -105,12 +97,14 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
show,
}) => {
const [filter, setFilter] = useState<any>(undefined);
const [pageIndex, setPageIndex] = useState<number>(0);
const [sortBy, setSortBy] = useState<SortByType>(DATASET_SORT_BY);
const [confirmChange, setConfirmChange] = useState(false);
const [confirmedDataset, setConfirmedDataset] = useState<Datasource>();
const searchRef = useRef<AntdInput>(null);

const {
state: { loading, resourceCollection },
state: { loading, resourceCollection, resourceCount },
fetchData,
} = useListViewResource<Dataset>('dataset', t('dataset'), addDangerToast);

Expand All @@ -119,10 +113,17 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
setConfirmedDataset(datasource);
}, []);

const fetchDatasetPayload = {
pageIndex,
pageSize: DATASET_PAGE_SIZE,
filters: [],
sortBy,
};

useDebouncedEffect(
() => {
fetchData({
...emptyRequest,
...fetchDatasetPayload,
...(filter && {
filters: [
{
Expand All @@ -134,8 +135,8 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
}),
});
},
300,
[filter],
SLOW_DEBOUNCE,
[filter, pageIndex, sortBy],
);

useEffect(() => {
Expand All @@ -159,6 +160,7 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
const changeSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
const searchValue = event.target.value ?? '';
setFilter(searchValue);
setPageIndex(0);
};

const handleChangeConfirm = () => {
Expand Down Expand Up @@ -187,25 +189,53 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
setConfirmChange(false);
};

const renderTableView = () => {
const data = resourceCollection.map((ds: any) => ({
rawName: ds.table_name,
connection: ds.database.database_name,
schema: ds.schema,
name: (
const columns = [
{
Cell: ({ row: { original } }: any) => (
<StyledSpan
role="button"
tabIndex={0}
data-test="datasource-link"
onClick={() => selectDatasource({ type: 'table', ...ds })}
onClick={() => selectDatasource({ type: 'table', ...original })}
>
{ds.table_name}
{original?.table_name}
</StyledSpan>
),
type: ds.kind,
}));
Header: t('Name'),
accessor: 'table_name',
},
{
Header: t('Type'),
accessor: 'kind',
disableSortBy: true,
},
{
Header: t('Schema'),
accessor: 'schema',
},
{
Header: t('Connection'),
accessor: 'database.database_name',
disableSortBy: true,
},
{
Cell: ({
row: {
original: { owners = [] },
},
}: any) => <FacePile users={owners} />,
Header: t('Owners'),
id: 'owners',
disableSortBy: true,
},
];

return data;
const onServerPagination = (args: ServerPagination) => {
setPageIndex(args.pageIndex);
if (args.sortBy) {
// ensure default sort by
setSortBy(args.sortBy.length > 0 ? args.sortBy : DATASET_SORT_BY);
}
};

return (
Expand All @@ -215,7 +245,7 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
responsive
title={t('Change dataset')}
width={confirmChange ? '432px' : ''}
height={confirmChange ? 'auto' : '480px'}
height={confirmChange ? 'auto' : '540px'}
hideFooter={!confirmChange}
footer={
<>
Expand Down Expand Up @@ -259,11 +289,17 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
{loading && <Loading />}
{!loading && (
<TableView
columns={TABLE_COLUMNS}
data={renderTableView()}
pageSize={20}
columns={columns}
data={resourceCollection}
pageSize={DATASET_PAGE_SIZE}
initialPageIndex={pageIndex}
initialSortBy={sortBy}
totalCount={resourceCount}
onServerPagination={onServerPagination}
className="table-condensed"
emptyWrapperType={EmptyWrapperType.Small}
serverPagination
isPaginationSticky
scrollTable
/>
)}
Expand Down
22 changes: 7 additions & 15 deletions superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx
Expand Up @@ -53,20 +53,12 @@ import ImportModelsModal from 'src/components/ImportModal/index';
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
import WarningIconWithTooltip from 'src/components/WarningIconWithTooltip';
import AddDatasetModal from './AddDatasetModal';

const PAGE_SIZE = 25;
const PASSWORDS_NEEDED_MESSAGE = t(
'The passwords for the databases below are needed in order to ' +
'import them together with the datasets. Please note that the ' +
'"Secure Extra" and "Certificate" sections of ' +
'the database configuration are not present in export files, and ' +
'should be added manually after the import if they are needed.',
);
const CONFIRM_OVERWRITE_MESSAGE = t(
'You are importing one or more datasets that already exist. ' +
'Overwriting might cause you to lose some of your work. Are you ' +
'sure you want to overwrite?',
);
import {
PAGE_SIZE,
SORT_BY,
PASSWORDS_NEEDED_MESSAGE,
CONFIRM_OVERWRITE_MESSAGE,
} from './constants';

const FlexRowContainer = styled.div`
align-items: center;
Expand Down Expand Up @@ -158,7 +150,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
const canCreate = hasPerm('can_write');
const canExport = hasPerm('can_read');

const initialSort = [{ id: 'changed_on_delta_humanized', desc: true }];
const initialSort = SORT_BY;

const openDatasetEditModal = useCallback(
({ id }: Dataset) => {
Expand Down

0 comments on commit 561ce9e

Please sign in to comment.