refactor: Moves CRUD features to src/features (#23482)
This commit is contained in:
parent
c5eecc7cc2
commit
adcb8cf0ac
|
|
@ -40,7 +40,7 @@ import { Input } from 'src/components/Input';
|
|||
import {
|
||||
PAGE_SIZE as DATASET_PAGE_SIZE,
|
||||
SORT_BY as DATASET_SORT_BY,
|
||||
} from 'src/views/CRUD/data/dataset/constants';
|
||||
} from 'src/features/datasets/constants';
|
||||
import withToasts from 'src/components/MessageToasts/withToasts';
|
||||
import FacePile from '../FacePile';
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import {
|
|||
} from '@superset-ui/core';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { Switch } from 'src/components/Switch';
|
||||
import { AlertObject } from 'src/views/CRUD/alert/types';
|
||||
import { AlertObject } from 'src/features/alerts/types';
|
||||
import { Menu } from 'src/components/Menu';
|
||||
import Checkbox from 'src/components/Checkbox';
|
||||
import { noOp } from 'src/utils/common';
|
||||
|
|
|
|||
|
|
@ -43,7 +43,12 @@ import { getClientErrorObject } from 'src/utils/getClientErrorObject';
|
|||
import withToasts from 'src/components/MessageToasts/withToasts';
|
||||
import { isFeatureEnabled } from 'src/featureFlags';
|
||||
import TagType from 'src/types/TagType';
|
||||
import { addTag, deleteTaggedObjects, fetchTags, OBJECT_TYPES } from 'src/tags';
|
||||
import {
|
||||
addTag,
|
||||
deleteTaggedObjects,
|
||||
fetchTags,
|
||||
OBJECT_TYPES,
|
||||
} from 'src/features/tags/tags';
|
||||
import { loadTags } from 'src/components/Tags/utils';
|
||||
|
||||
const StyledFormItem = styled(FormItem)`
|
||||
|
|
|
|||
|
|
@ -34,7 +34,12 @@ import Chart, { Slice } from 'src/types/Chart';
|
|||
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||
import withToasts from 'src/components/MessageToasts/withToasts';
|
||||
import { loadTags } from 'src/components/Tags/utils';
|
||||
import { addTag, deleteTaggedObjects, fetchTags, OBJECT_TYPES } from 'src/tags';
|
||||
import {
|
||||
addTag,
|
||||
deleteTaggedObjects,
|
||||
fetchTags,
|
||||
OBJECT_TYPES,
|
||||
} from 'src/features/tags/tags';
|
||||
import TagType from 'src/types/TagType';
|
||||
|
||||
export type PropertiesModalProps = {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import thunk from 'redux-thunk';
|
|||
import configureStore from 'redux-mock-store';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import AlertReportModal from 'src/views/CRUD/alert/AlertReportModal';
|
||||
import Modal from 'src/components/Modal';
|
||||
import { Select, AsyncSelect } from 'src/components';
|
||||
import { Switch } from 'src/components/Switch';
|
||||
|
|
@ -30,6 +29,7 @@ import { Radio } from 'src/components/Radio';
|
|||
import TextAreaControl from 'src/explore/components/controls/TextAreaControl';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import AlertReportModal from './AlertReportModal';
|
||||
|
||||
const mockData = {
|
||||
active: true,
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
import React from 'react';
|
||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import AlertReportModal from 'src/views/CRUD/alert/AlertReportModal';
|
||||
import AlertReportModal from './AlertReportModal';
|
||||
|
||||
test('allows change to None in log retention', async () => {
|
||||
render(<AlertReportModal show />, { useRedux: true });
|
||||
|
|
@ -45,7 +45,8 @@ import withToasts from 'src/components/MessageToasts/withToasts';
|
|||
import Owner from 'src/types/Owner';
|
||||
import { AntdCheckbox, AsyncSelect, Select } from 'src/components';
|
||||
import TextAreaControl from 'src/explore/components/controls/TextAreaControl';
|
||||
import { useCommonConf } from 'src/views/CRUD/data/database/state';
|
||||
import { useCommonConf } from 'src/features/databases/state';
|
||||
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
|
||||
import {
|
||||
NotificationMethodOption,
|
||||
AlertObject,
|
||||
|
|
@ -56,8 +57,7 @@ import {
|
|||
Operator,
|
||||
Recipient,
|
||||
AlertsReportsConfig,
|
||||
} from 'src/views/CRUD/alert/types';
|
||||
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
|
||||
} from 'src/features/alerts/types';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AlertReportCronScheduler } from './components/AlertReportCronScheduler';
|
||||
import { NotificationMethod } from './components/NotificationMethod';
|
||||
|
|
@ -23,7 +23,7 @@ import { AntdInput, RadioChangeEvent } from 'src/components';
|
|||
import { Input } from 'src/components/Input';
|
||||
import { Radio } from 'src/components/Radio';
|
||||
import { CronPicker, CronError } from 'src/components/CronPicker';
|
||||
import { StyledInputContainer } from 'src/views/CRUD/alert/AlertReportModal';
|
||||
import { StyledInputContainer } from '../AlertReportModal';
|
||||
|
||||
export interface AlertReportCronSchedulerProps {
|
||||
value: string;
|
||||
|
|
@ -20,7 +20,7 @@ import React, { FunctionComponent, useState } from 'react';
|
|||
import { styled, t, useTheme } from '@superset-ui/core';
|
||||
import { Select } from 'src/components';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { NotificationMethodOption } from 'src/views/CRUD/alert/types';
|
||||
import { NotificationMethodOption } from '../types';
|
||||
import { StyledInputContainer } from '../AlertReportModal';
|
||||
|
||||
const StyledNotificationMethod = styled.div`
|
||||
|
|
@ -21,8 +21,8 @@ import moment from 'moment';
|
|||
import { t, styled, logging } from '@superset-ui/core';
|
||||
import TableView, { EmptyWrapperType } from 'src/components/TableView';
|
||||
import { addDangerToast } from 'src/components/MessageToasts/actions';
|
||||
import { fetchObjects } from '../../../tags';
|
||||
import Loading from '../../../components/Loading';
|
||||
import Loading from 'src/components/Loading';
|
||||
import { fetchObjects } from '../tags/tags';
|
||||
|
||||
const AllEntitiesTableContainer = styled.div`
|
||||
text-align: left;
|
||||
|
|
@ -21,10 +21,10 @@ import thunk from 'redux-thunk';
|
|||
import configureStore from 'redux-mock-store';
|
||||
import { Provider } from 'react-redux';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import AnnotationLayerModal from 'src/views/CRUD/annotationlayers/AnnotationLayerModal';
|
||||
import Modal from 'src/components/Modal';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import AnnotationLayerModal from './AnnotationLayerModal';
|
||||
|
||||
const mockData = { id: 1, name: 'test', descr: 'test description' };
|
||||
const FETCH_ANNOTATION_LAYER_ENDPOINT = 'glob:*/api/v1/annotation_layer/*';
|
||||
|
|
@ -21,11 +21,11 @@ import thunk from 'redux-thunk';
|
|||
import configureStore from 'redux-mock-store';
|
||||
import { Provider } from 'react-redux';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import AnnotationModal from 'src/views/CRUD/annotation/AnnotationModal';
|
||||
import Modal from 'src/components/Modal';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { JsonEditor } from 'src/components/AsyncAceEditor';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import AnnotationModal from './AnnotationModal';
|
||||
|
||||
const mockData = {
|
||||
id: 1,
|
||||
|
|
@ -21,11 +21,11 @@ import thunk from 'redux-thunk';
|
|||
import { Provider } from 'react-redux';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import CssTemplateModal from 'src/views/CRUD/csstemplates/CssTemplateModal';
|
||||
import Modal from 'src/components/Modal';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { CssEditor } from 'src/components/AsyncAceEditor';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import CssTemplateModal from './CssTemplateModal';
|
||||
|
||||
const mockData = { id: 1, template_name: 'test' };
|
||||
const FETCH_CSS_TEMPLATE_ENDPOINT = 'glob:*/api/v1/css_template/*';
|
||||
|
|
@ -24,7 +24,6 @@ import { Radio } from 'src/components/Radio';
|
|||
import { Input, TextArea } from 'src/components/Input';
|
||||
import { Input as AntdInput, Tooltip } from 'antd';
|
||||
import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
|
||||
|
||||
import { DatabaseObject } from '../types';
|
||||
import { AuthType } from '.';
|
||||
|
||||
|
|
@ -21,7 +21,6 @@ import { t, SupersetTheme } from '@superset-ui/core';
|
|||
import SupersetText from 'src/utils/textUtils';
|
||||
import Button from 'src/components/Button';
|
||||
import { StyledInputContainer, wideButton } from './styles';
|
||||
|
||||
import { DatabaseObject } from '../types';
|
||||
|
||||
const SqlAlchemyTab = ({
|
||||
|
|
@ -27,13 +27,10 @@ import {
|
|||
act,
|
||||
waitFor,
|
||||
} from 'spec/helpers/testing-library';
|
||||
import {
|
||||
DatabaseObject,
|
||||
CONFIGURATION_METHOD,
|
||||
} from 'src/views/CRUD/data/database/types';
|
||||
import { getExtensionsRegistry } from '@superset-ui/core';
|
||||
import setupExtensions from 'src/setup/setupExtensions';
|
||||
import * as hooks from 'src/views/CRUD/hooks';
|
||||
import { DatabaseObject, CONFIGURATION_METHOD } from '../types';
|
||||
import DatabaseModal, {
|
||||
dbReducer,
|
||||
DBReducerActionType,
|
||||
|
|
@ -54,7 +54,9 @@ import {
|
|||
getConnectionAlert,
|
||||
useImportResource,
|
||||
} from 'src/views/CRUD/hooks';
|
||||
import { useCommonConf } from 'src/views/CRUD/data/database/state';
|
||||
import { useCommonConf } from 'src/features/databases/state';
|
||||
import Loading from 'src/components/Loading';
|
||||
import { isEmpty, pick } from 'lodash';
|
||||
import {
|
||||
DatabaseObject,
|
||||
DatabaseForm,
|
||||
|
|
@ -62,9 +64,7 @@ import {
|
|||
CatalogObject,
|
||||
Engines,
|
||||
ExtraJson,
|
||||
} from 'src/views/CRUD/data/database/types';
|
||||
import Loading from 'src/components/Loading';
|
||||
import { isEmpty, pick } from 'lodash';
|
||||
} from '../types';
|
||||
import ExtraOptions from './ExtraOptions';
|
||||
import SqlAlchemyForm from './SqlAlchemyForm';
|
||||
import DatabaseConnectionForm from './DatabaseConnectionForm';
|
||||
|
|
@ -23,7 +23,7 @@ import DatasetPanel, {
|
|||
ALT_LOADING,
|
||||
tableColumnDefinition,
|
||||
COLUMN_TITLE,
|
||||
} from 'src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel';
|
||||
} from 'src/features/datasets/AddDataset/DatasetPanel/DatasetPanel';
|
||||
import { exampleColumns, exampleDataset } from './fixtures';
|
||||
import {
|
||||
SELECT_MESSAGE,
|
||||
|
|
@ -24,7 +24,7 @@ import Table, { ColumnsType, TableSize } from 'src/components/Table';
|
|||
import { alphabeticalSort } from 'src/components/Table/sorters';
|
||||
// @ts-ignore
|
||||
import LOADING_GIF from 'src/assets/images/loading.gif';
|
||||
import { DatasetObject } from 'src/views/CRUD/data/dataset/AddDataset/types';
|
||||
import { DatasetObject } from 'src/features/datasets/AddDataset/types';
|
||||
import { ITableColumn } from './types';
|
||||
import MessageContent from './MessageContent';
|
||||
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { DatasetObject } from 'src/views/CRUD/data/dataset/AddDataset/types';
|
||||
import { DatasetObject } from 'src/features/datasets/AddDataset/types';
|
||||
import { ITableColumn } from './types';
|
||||
|
||||
export const exampleColumns: ITableColumn[] = [
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { SupersetClient, logging, t } from '@superset-ui/core';
|
||||
import { DatasetObject } from 'src/views/CRUD/data/dataset/AddDataset/types';
|
||||
import { DatasetObject } from 'src/features/datasets/AddDataset/types';
|
||||
import { addDangerToast } from 'src/components/MessageToasts/actions';
|
||||
import DatasetPanel from './DatasetPanel';
|
||||
import { ITableColumn, IDatabaseTable, isIDatabaseTable } from './types';
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
import { styled, t } from '@superset-ui/core';
|
||||
import React from 'react';
|
||||
import { useGetDatasetRelatedCounts } from 'src/views/CRUD/data/hooks';
|
||||
import useGetDatasetRelatedCounts from 'src/features/datasets/hooks/useGetDatasetRelatedCounts';
|
||||
import Badge from 'src/components/Badge';
|
||||
import Tabs from 'src/components/Tabs';
|
||||
import UsageTab from './UsageTab';
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
import Footer from 'src/views/CRUD/data/dataset/AddDataset/Footer';
|
||||
import Footer from 'src/features/datasets/AddDataset/Footer';
|
||||
|
||||
const mockHistoryPush = jest.fn();
|
||||
jest.mock('react-router-dom', () => ({
|
||||
|
|
@ -18,9 +18,7 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import Header, {
|
||||
DEFAULT_TITLE,
|
||||
} from 'src/views/CRUD/data/dataset/AddDataset/Header';
|
||||
import Header, { DEFAULT_TITLE } from 'src/features/datasets/AddDataset/Header';
|
||||
|
||||
describe('Header', () => {
|
||||
const mockSetDataset = jest.fn();
|
||||
|
|
@ -23,15 +23,15 @@ import Button from 'src/components/Button';
|
|||
import Icons from 'src/components/Icons';
|
||||
import { Menu } from 'src/components/Menu';
|
||||
import { TooltipPlacement } from 'src/components/Tooltip';
|
||||
import {
|
||||
DatasetActionType,
|
||||
DSReducerActionType,
|
||||
} from 'src/features/datasets/AddDataset/types';
|
||||
import {
|
||||
HeaderComponentStyles,
|
||||
disabledSaveBtnStyles,
|
||||
StyledCreateDatasetTitle,
|
||||
} from 'src/views/CRUD/data/dataset/styles';
|
||||
import {
|
||||
DatasetActionType,
|
||||
DSReducerActionType,
|
||||
} from 'src/views/CRUD/data/dataset/AddDataset/types';
|
||||
} from '../../styles';
|
||||
|
||||
export const DEFAULT_TITLE = t('New dataset');
|
||||
|
||||
|
|
@ -20,8 +20,8 @@ import React from 'react';
|
|||
import fetchMock from 'fetch-mock';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import LeftPanel from 'src/views/CRUD/data/dataset/AddDataset/LeftPanel';
|
||||
import { exampleDataset } from 'src/views/CRUD/data/dataset/AddDataset/DatasetPanel/fixtures';
|
||||
import LeftPanel from 'src/features/datasets/AddDataset/LeftPanel';
|
||||
import { exampleDataset } from 'src/features/datasets/AddDataset/DatasetPanel/fixtures';
|
||||
|
||||
const databasesEndpoint = 'glob:*/api/v1/database/?q*';
|
||||
const schemasEndpoint = 'glob:*/api/v1/database/*/schemas*';
|
||||
|
|
@ -51,7 +51,7 @@ import { LocalStorageKeys, getItem } from 'src/utils/localStorageHelpers';
|
|||
import {
|
||||
DatasetActionType,
|
||||
DatasetObject,
|
||||
} from 'src/views/CRUD/data/dataset/AddDataset/types';
|
||||
} from 'src/features/datasets/AddDataset/types';
|
||||
|
||||
interface LeftPanelProps {
|
||||
setDataset: Dispatch<SetStateAction<object>>;
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
import RightPanel from 'src/views/CRUD/data/dataset/AddDataset/RightPanel';
|
||||
import RightPanel from 'src/features/datasets/AddDataset/RightPanel';
|
||||
|
||||
describe('RightPanel', () => {
|
||||
it('renders a blank state RightPanel', () => {
|
||||
|
|
@ -18,12 +18,12 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import DatasetLayout from 'src/views/CRUD/data/dataset/DatasetLayout';
|
||||
import Header from 'src/views/CRUD/data/dataset/AddDataset/Header';
|
||||
import LeftPanel from 'src/views/CRUD/data/dataset/AddDataset/LeftPanel';
|
||||
import DatasetPanel from 'src/views/CRUD/data/dataset/AddDataset/DatasetPanel';
|
||||
import RightPanel from 'src/views/CRUD/data/dataset/AddDataset/RightPanel';
|
||||
import Footer from 'src/views/CRUD/data/dataset/AddDataset/Footer';
|
||||
import DatasetLayout from 'src/features/datasets/DatasetLayout';
|
||||
import Header from 'src/features/datasets/AddDataset/Header';
|
||||
import LeftPanel from 'src/features/datasets/AddDataset/LeftPanel';
|
||||
import DatasetPanel from 'src/features/datasets/AddDataset/DatasetPanel';
|
||||
import RightPanel from 'src/features/datasets/AddDataset/RightPanel';
|
||||
import Footer from 'src/features/datasets/AddDataset/Footer';
|
||||
|
||||
const mockHistoryPush = jest.fn();
|
||||
jest.mock('react-router-dom', () => ({
|
||||
|
|
@ -29,7 +29,7 @@ import {
|
|||
StyledLayoutDatasetPanel,
|
||||
StyledLayoutRightPanel,
|
||||
StyledLayoutFooter,
|
||||
} from 'src/views/CRUD/data/dataset/styles';
|
||||
} from '../styles';
|
||||
|
||||
interface DatasetLayoutProps {
|
||||
header?: ReactElement<any, string | JSXElementConstructor<any>> | null;
|
||||
|
|
@ -20,70 +20,13 @@ import { useState, useEffect, useCallback } from 'react';
|
|||
import { SupersetClient, logging, t } from '@superset-ui/core';
|
||||
import rison from 'rison';
|
||||
import { addDangerToast } from 'src/components/MessageToasts/actions';
|
||||
import { DatasetObject } from 'src/views/CRUD/data/dataset/AddDataset/types';
|
||||
import { DatasetObject } from 'src/features/datasets/AddDataset/types';
|
||||
import { DatabaseObject } from 'src/components/DatabaseSelector';
|
||||
|
||||
type BaseQueryObject = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
export function useQueryPreviewState<D extends BaseQueryObject = any>({
|
||||
queries,
|
||||
fetchData,
|
||||
currentQueryId,
|
||||
}: {
|
||||
queries: D[];
|
||||
fetchData: (id: number) => any;
|
||||
currentQueryId: number;
|
||||
}) {
|
||||
const index = queries.findIndex(query => query.id === currentQueryId);
|
||||
const [currentIndex, setCurrentIndex] = useState(index);
|
||||
const [disablePrevious, setDisablePrevious] = useState(false);
|
||||
const [disableNext, setDisableNext] = useState(false);
|
||||
|
||||
function checkIndex() {
|
||||
setDisablePrevious(currentIndex === 0);
|
||||
setDisableNext(currentIndex === queries.length - 1);
|
||||
}
|
||||
|
||||
function handleDataChange(previous: boolean) {
|
||||
const offset = previous ? -1 : 1;
|
||||
const index = currentIndex + offset;
|
||||
if (index >= 0 && index < queries.length) {
|
||||
fetchData(queries[index].id);
|
||||
setCurrentIndex(index);
|
||||
checkIndex();
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyPress(ev: any) {
|
||||
if (currentIndex >= 0 && currentIndex < queries.length) {
|
||||
if (ev.key === 'ArrowDown' || ev.key === 'k') {
|
||||
ev.preventDefault();
|
||||
handleDataChange(false);
|
||||
} else if (ev.key === 'ArrowUp' || ev.key === 'j') {
|
||||
ev.preventDefault();
|
||||
handleDataChange(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkIndex();
|
||||
});
|
||||
|
||||
return {
|
||||
handleKeyPress,
|
||||
handleDataChange,
|
||||
disablePrevious,
|
||||
disableNext,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all pages of dataset results
|
||||
*/
|
||||
export const useDatasetsList = (
|
||||
const useDatasetsList = (
|
||||
db:
|
||||
| (DatabaseObject & {
|
||||
owners: [number];
|
||||
|
|
@ -145,34 +88,4 @@ export const useDatasetsList = (
|
|||
return { datasets, datasetNames };
|
||||
};
|
||||
|
||||
export const useGetDatasetRelatedCounts = (id: string) => {
|
||||
const [usageCount, setUsageCount] = useState(0);
|
||||
|
||||
const getDatasetRelatedObjects = useCallback(
|
||||
() =>
|
||||
SupersetClient.get({
|
||||
endpoint: `/api/v1/dataset/${id}/related_objects`,
|
||||
})
|
||||
.then(({ json }) => {
|
||||
setUsageCount(json?.charts.count);
|
||||
})
|
||||
.catch(error => {
|
||||
addDangerToast(
|
||||
t(`There was an error fetching dataset's related objects`),
|
||||
);
|
||||
logging.error(error);
|
||||
}),
|
||||
[id],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Todo: this useEffect should be used to call all count methods conncurently
|
||||
// when we populate data for the new tabs. For right separating out this
|
||||
// api call for building the usage page.
|
||||
if (id) {
|
||||
getDatasetRelatedObjects();
|
||||
}
|
||||
}, [id, getDatasetRelatedObjects]);
|
||||
|
||||
return { usageCount };
|
||||
};
|
||||
export default useDatasetsList;
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* 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 { useState, useEffect, useCallback } from 'react';
|
||||
import { SupersetClient, logging, t } from '@superset-ui/core';
|
||||
import { addDangerToast } from 'src/components/MessageToasts/actions';
|
||||
|
||||
const useGetDatasetRelatedCounts = (id: string) => {
|
||||
const [usageCount, setUsageCount] = useState(0);
|
||||
|
||||
const getDatasetRelatedObjects = useCallback(
|
||||
() =>
|
||||
SupersetClient.get({
|
||||
endpoint: `/api/v1/dataset/${id}/related_objects`,
|
||||
})
|
||||
.then(({ json }) => {
|
||||
setUsageCount(json?.charts.count);
|
||||
})
|
||||
.catch(error => {
|
||||
addDangerToast(
|
||||
t(`There was an error fetching dataset's related objects`),
|
||||
);
|
||||
logging.error(error);
|
||||
}),
|
||||
[id],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Todo: this useEffect should be used to call all count methods conncurently
|
||||
// when we populate data for the new tabs. For right separating out this
|
||||
// api call for building the usage page.
|
||||
if (id) {
|
||||
getDatasetRelatedObjects();
|
||||
}
|
||||
}, [id, getDatasetRelatedObjects]);
|
||||
|
||||
return { usageCount };
|
||||
};
|
||||
|
||||
export default useGetDatasetRelatedCounts;
|
||||
|
|
@ -24,8 +24,8 @@ import { Provider } from 'react-redux';
|
|||
import fetchMock from 'fetch-mock';
|
||||
import thunk from 'redux-thunk';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import ActivityTable from 'src/views/CRUD/welcome/ActivityTable';
|
||||
import { TableTab } from 'src/views/CRUD/types';
|
||||
import ActivityTable from './ActivityTable';
|
||||
|
||||
const mockStore = configureStore([thunk]);
|
||||
const store = mockStore({});
|
||||
|
|
@ -22,7 +22,6 @@ import { styled, t } from '@superset-ui/core';
|
|||
import { setItem, LocalStorageKeys } from 'src/utils/localStorageHelpers';
|
||||
import { Link } from 'react-router-dom';
|
||||
import ListViewCard from 'src/components/ListViewCard';
|
||||
import SubMenu from 'src/views/components/SubMenu';
|
||||
import { Dashboard, SavedQueryObject, TableTab } from 'src/views/CRUD/types';
|
||||
import { ActivityData, LoadingCards } from 'src/pages/Home';
|
||||
import {
|
||||
|
|
@ -31,9 +30,8 @@ import {
|
|||
getEditedObjects,
|
||||
} from 'src/views/CRUD/utils';
|
||||
import { Chart } from 'src/types/Chart';
|
||||
|
||||
import Icons from 'src/components/Icons';
|
||||
|
||||
import SubMenu from './SubMenu';
|
||||
import EmptyState from './EmptyState';
|
||||
import { WelcomeTable } from './types';
|
||||
|
||||
|
|
@ -21,11 +21,10 @@ import { styledMount as mount } from 'spec/helpers/theming';
|
|||
import thunk from 'redux-thunk';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import ChartTable from 'src/views/CRUD/welcome/ChartTable';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import ChartTable from './ChartTable';
|
||||
|
||||
const mockStore = configureStore([thunk]);
|
||||
const store = mockStore({});
|
||||
|
|
@ -40,14 +40,14 @@ import {
|
|||
PAGE_SIZE,
|
||||
} from 'src/views/CRUD/utils';
|
||||
import { LoadingCards } from 'src/pages/Home';
|
||||
import ChartCard from 'src/views/CRUD/chart/ChartCard';
|
||||
import ChartCard from 'src/features/charts/ChartCard';
|
||||
import Chart from 'src/types/Chart';
|
||||
import handleResourceExport from 'src/utils/export';
|
||||
import Loading from 'src/components/Loading';
|
||||
import ErrorBoundary from 'src/components/ErrorBoundary';
|
||||
import SubMenu from 'src/views/components/SubMenu';
|
||||
import EmptyState from './EmptyState';
|
||||
import { WelcomeTable } from './types';
|
||||
import SubMenu from './SubMenu';
|
||||
|
||||
interface ChartTableProps {
|
||||
addDangerToast: (message: string) => void;
|
||||
|
|
@ -24,8 +24,8 @@ import fetchMock from 'fetch-mock';
|
|||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import DashboardTable from 'src/views/CRUD/welcome/DashboardTable';
|
||||
import DashboardCard from 'src/views/CRUD/dashboard/DashboardCard';
|
||||
import DashboardCard from 'src/features/dashboards/DashboardCard';
|
||||
import DashboardTable from './DashboardTable';
|
||||
|
||||
// store needed for withToasts(DashboardTable)
|
||||
const mockStore = configureStore([thunk]);
|
||||
|
|
@ -40,9 +40,9 @@ import withToasts from 'src/components/MessageToasts/withToasts';
|
|||
import Loading from 'src/components/Loading';
|
||||
import DeleteModal from 'src/components/DeleteModal';
|
||||
import PropertiesModal from 'src/dashboard/components/PropertiesModal';
|
||||
import DashboardCard from 'src/views/CRUD/dashboard/DashboardCard';
|
||||
import SubMenu from 'src/views/components/SubMenu';
|
||||
import DashboardCard from 'src/features/dashboards/DashboardCard';
|
||||
import EmptyState from './EmptyState';
|
||||
import SubMenu from './SubMenu';
|
||||
import { WelcomeTable } from './types';
|
||||
|
||||
function DashboardTable({
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
import React from 'react';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import { TableTab } from 'src/views/CRUD/types';
|
||||
import EmptyState, { EmptyStateProps } from 'src/views/CRUD/welcome/EmptyState';
|
||||
import EmptyState, { EmptyStateProps } from './EmptyState';
|
||||
import { WelcomeTable } from './types';
|
||||
|
||||
describe('EmptyState', () => {
|
||||
|
|
@ -29,7 +29,7 @@ jest.mock('react-redux', () => ({
|
|||
useSelector: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('src/views/CRUD/data/database/DatabaseModal', () => () => <span />);
|
||||
jest.mock('src/features/databases/DatabaseModal', () => () => <span />);
|
||||
|
||||
const dropdownItems = [
|
||||
{
|
||||
|
|
@ -44,9 +44,9 @@ import {
|
|||
MenuObjectChildProps,
|
||||
} from 'src/types/bootstrapTypes';
|
||||
import { RootState } from 'src/dashboard/types';
|
||||
import DatabaseModal from 'src/features/databases/DatabaseModal';
|
||||
import { uploadUserPerms } from 'src/views/CRUD/utils';
|
||||
import LanguagePicker from './LanguagePicker';
|
||||
import DatabaseModal from '../CRUD/data/database/DatabaseModal';
|
||||
import { uploadUserPerms } from '../CRUD/utils';
|
||||
import {
|
||||
ExtensionConfigs,
|
||||
GlobalMenuDataOptions,
|
||||
|
|
@ -67,10 +67,9 @@ const StyledI = styled.div`
|
|||
`;
|
||||
|
||||
const styledDisabled = (theme: SupersetTheme) => css`
|
||||
color: ${theme.colors.grayscale.base};
|
||||
backgroundColor: ${theme.colors.grayscale.light2}};
|
||||
.ant-menu-item:hover {
|
||||
color: ${theme.colors.grayscale.base};
|
||||
color: ${theme.colors.grayscale.light1};
|
||||
.ant-menu-item-active {
|
||||
color: ${theme.colors.grayscale.light1};
|
||||
cursor: default;
|
||||
}
|
||||
`;
|
||||
|
|
@ -22,10 +22,9 @@ import { styledMount as mount } from 'spec/helpers/theming';
|
|||
import fetchMock from 'fetch-mock';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import SubMenu from 'src/views/components/SubMenu';
|
||||
import SavedQueries from 'src/views/CRUD/welcome/SavedQueries';
|
||||
import SubMenu from './SubMenu';
|
||||
import SavedQueries from './SavedQueries';
|
||||
|
||||
// store needed for withToasts(DashboardTable)
|
||||
const mockStore = configureStore([thunk]);
|
||||
|
|
@ -30,16 +30,16 @@ import { copyQueryLink, useListViewResource } from 'src/views/CRUD/hooks';
|
|||
import ListViewCard from 'src/components/ListViewCard';
|
||||
import DeleteModal from 'src/components/DeleteModal';
|
||||
import Icons from 'src/components/Icons';
|
||||
import SubMenu from 'src/views/components/SubMenu';
|
||||
import { User } from 'src/types/bootstrapTypes';
|
||||
import EmptyState from './EmptyState';
|
||||
import {
|
||||
CardContainer,
|
||||
createErrorHandler,
|
||||
getFilterValues,
|
||||
PAGE_SIZE,
|
||||
shortenSQL,
|
||||
} from '../utils';
|
||||
} from 'src/views/CRUD/utils';
|
||||
import SubMenu from './SubMenu';
|
||||
import EmptyState from './EmptyState';
|
||||
import { WelcomeTable } from './types';
|
||||
|
||||
SyntaxHighlighter.registerLanguage('sql', sql);
|
||||
|
|
@ -161,11 +161,10 @@ const StyledHeader = styled.div`
|
|||
`;
|
||||
|
||||
const styledDisabled = (theme: SupersetTheme) => css`
|
||||
color: ${theme.colors.grayscale.base};
|
||||
backgroundColor: ${theme.colors.grayscale.light2}};
|
||||
color: ${theme.colors.grayscale.light1};
|
||||
|
||||
.ant-menu-item:hover {
|
||||
color: ${theme.colors.grayscale.base};
|
||||
.ant-menu-item-active {
|
||||
color: ${theme.colors.grayscale.light1};
|
||||
cursor: default;
|
||||
}
|
||||
`;
|
||||
|
|
@ -17,8 +17,18 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { Filter } from 'src/views/CRUD/types';
|
||||
import { NavBarProps, MenuObjectProps } from 'src/types/bootstrapTypes';
|
||||
|
||||
export enum WelcomeTable {
|
||||
Charts = 'CHARTS',
|
||||
Dashboards = 'DASHBOARDS',
|
||||
Recents = 'RECENTS',
|
||||
SavedQueries = 'SAVED_QUERIES',
|
||||
}
|
||||
|
||||
export type WelcomePageLastTab = 'examples' | 'all' | [string, Filter[]];
|
||||
|
||||
export interface ExtensionConfigs {
|
||||
ALLOWED_EXTENSIONS: Array<any>;
|
||||
CSV_EXTENSIONS: Array<any>;
|
||||
|
|
@ -23,11 +23,11 @@ import configureStore from 'redux-mock-store';
|
|||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
|
||||
import QueryPreviewModal from 'src/views/CRUD/data/query/QueryPreviewModal';
|
||||
import { QueryObject } from 'src/views/CRUD/types';
|
||||
import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/light';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { QueryState } from '@superset-ui/core';
|
||||
import QueryPreviewModal from './QueryPreviewModal';
|
||||
|
||||
// store needed for withToasts
|
||||
const mockStore = configureStore([thunk]);
|
||||
|
|
@ -24,8 +24,8 @@ import Button from 'src/components/Button';
|
|||
import withToasts, {
|
||||
ToastProps,
|
||||
} from 'src/components/MessageToasts/withToasts';
|
||||
import SyntaxHighlighterCopy from 'src/views/CRUD/data/components/SyntaxHighlighterCopy';
|
||||
import { useQueryPreviewState } from 'src/views/CRUD/data/hooks';
|
||||
import SyntaxHighlighterCopy from 'src/features/queries/SyntaxHighlighterCopy';
|
||||
import useQueryPreviewState from 'src/features/queries/hooks/useQueryPreviewState';
|
||||
import { QueryObject } from 'src/views/CRUD/types';
|
||||
|
||||
const QueryTitle = styled.div`
|
||||
|
|
@ -21,11 +21,11 @@ import thunk from 'redux-thunk';
|
|||
import configureStore from 'redux-mock-store';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { styledMount as mount } from 'spec/helpers/theming';
|
||||
import SavedQueryPreviewModal from 'src/views/CRUD/data/savedquery/SavedQueryPreviewModal';
|
||||
import Button from 'src/components/Button';
|
||||
import Modal from 'src/components/Modal';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import SavedQueryPreviewModal from './SavedQueryPreviewModal';
|
||||
|
||||
// store needed for withToasts(DatabaseList)
|
||||
const mockStore = configureStore([thunk]);
|
||||
|
|
@ -20,11 +20,11 @@ import React, { FunctionComponent } from 'react';
|
|||
import { styled, t } from '@superset-ui/core';
|
||||
import Modal from 'src/components/Modal';
|
||||
import Button from 'src/components/Button';
|
||||
import SyntaxHighlighterCopy from 'src/views/CRUD/data/components/SyntaxHighlighterCopy';
|
||||
import SyntaxHighlighterCopy from 'src/features/queries/SyntaxHighlighterCopy';
|
||||
import withToasts, {
|
||||
ToastProps,
|
||||
} from 'src/components/MessageToasts/withToasts';
|
||||
import { useQueryPreviewState } from 'src/views/CRUD/data/hooks';
|
||||
import useQueryPreviewState from 'src/features/queries/hooks/useQueryPreviewState';
|
||||
|
||||
const QueryTitle = styled.div`
|
||||
color: ${({ theme }) => theme.colors.secondary.light2};
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* 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 { useState, useEffect } from 'react';
|
||||
|
||||
type BaseQueryObject = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
export default function useQueryPreviewState<D extends BaseQueryObject = any>({
|
||||
queries,
|
||||
fetchData,
|
||||
currentQueryId,
|
||||
}: {
|
||||
queries: D[];
|
||||
fetchData: (id: number) => any;
|
||||
currentQueryId: number;
|
||||
}) {
|
||||
const index = queries.findIndex(query => query.id === currentQueryId);
|
||||
const [currentIndex, setCurrentIndex] = useState(index);
|
||||
const [disablePrevious, setDisablePrevious] = useState(false);
|
||||
const [disableNext, setDisableNext] = useState(false);
|
||||
|
||||
function checkIndex() {
|
||||
setDisablePrevious(currentIndex === 0);
|
||||
setDisableNext(currentIndex === queries.length - 1);
|
||||
}
|
||||
|
||||
function handleDataChange(previous: boolean) {
|
||||
const offset = previous ? -1 : 1;
|
||||
const index = currentIndex + offset;
|
||||
if (index >= 0 && index < queries.length) {
|
||||
fetchData(queries[index].id);
|
||||
setCurrentIndex(index);
|
||||
checkIndex();
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyPress(ev: any) {
|
||||
if (currentIndex >= 0 && currentIndex < queries.length) {
|
||||
if (ev.key === 'ArrowDown' || ev.key === 'k') {
|
||||
ev.preventDefault();
|
||||
handleDataChange(false);
|
||||
} else if (ev.key === 'ArrowUp' || ev.key === 'j') {
|
||||
ev.preventDefault();
|
||||
handleDataChange(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkIndex();
|
||||
});
|
||||
|
||||
return {
|
||||
handleKeyPress,
|
||||
handleDataChange,
|
||||
disablePrevious,
|
||||
disableNext,
|
||||
};
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
|
|||
import ListViewCard from 'src/components/ListViewCard';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { Tag } from 'src/views/CRUD/types';
|
||||
import { deleteTags } from 'src/tags';
|
||||
import { deleteTags } from 'src/features/tags/tags';
|
||||
|
||||
interface TagCardProps {
|
||||
tag: Tag;
|
||||
|
|
@ -25,7 +25,7 @@ import { styledMount as mount } from 'spec/helpers/theming';
|
|||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { Switch } from 'src/components/Switch';
|
||||
import ListView from 'src/components/ListView';
|
||||
import SubMenu from 'src/views/components/SubMenu';
|
||||
import SubMenu from 'src/features/home/SubMenu';
|
||||
import AlertList from 'src/pages/AlertReportList';
|
||||
import IndeterminateCheckbox from 'src/components/IndeterminateCheckbox';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
|
|
|||
|
|
@ -35,16 +35,15 @@ import ListView, {
|
|||
Filters,
|
||||
ListViewProps,
|
||||
} from 'src/components/ListView';
|
||||
import SubMenu, { SubMenuProps } from 'src/views/components/SubMenu';
|
||||
import SubMenu, { SubMenuProps } from 'src/features/home/SubMenu';
|
||||
import { Switch } from 'src/components/Switch';
|
||||
import { DATETIME_WITH_TIME_ZONE } from 'src/constants';
|
||||
import withToasts from 'src/components/MessageToasts/withToasts';
|
||||
import AlertStatusIcon from 'src/views/CRUD/alert/components/AlertStatusIcon';
|
||||
import RecipientIcon from 'src/views/CRUD/alert/components/RecipientIcon';
|
||||
import AlertStatusIcon from 'src/features/alerts/components/AlertStatusIcon';
|
||||
import RecipientIcon from 'src/features/alerts/components/RecipientIcon';
|
||||
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
|
||||
import DeleteModal from 'src/components/DeleteModal';
|
||||
import LastUpdated from 'src/components/LastUpdated';
|
||||
|
||||
import {
|
||||
useListViewResource,
|
||||
useSingleViewResource,
|
||||
|
|
@ -52,8 +51,8 @@ import {
|
|||
import { createErrorHandler, createFetchRelated } from 'src/views/CRUD/utils';
|
||||
import { isUserAdmin } from 'src/dashboard/util/permissionUtils';
|
||||
import Owner from 'src/types/Owner';
|
||||
import AlertReportModal from 'src/views/CRUD/alert/AlertReportModal';
|
||||
import { AlertObject, AlertState } from 'src/views/CRUD/alert/types';
|
||||
import AlertReportModal from 'src/features/alerts/AlertReportModal';
|
||||
import { AlertObject, AlertState } from 'src/features/alerts/types';
|
||||
|
||||
const extensionsRegistry = getExtensionsRegistry();
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import AsyncSelect from 'src/components/Select/AsyncSelect';
|
|||
import { SelectValue } from 'antd/lib/select';
|
||||
import { loadTags } from 'src/components/Tags/utils';
|
||||
import { getValue } from 'src/components/Select/utils';
|
||||
import AllEntitiesTable from 'src/views/CRUD/allentities/AllEntitiesTable';
|
||||
import AllEntitiesTable from 'src/features/allEntities/AllEntitiesTable';
|
||||
|
||||
const AllEntitiesContainer = styled.div`
|
||||
${({ theme }) => `
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue