mirror of https://github.com/apache/superset.git
fix: Table sorting reset (#23318)
This commit is contained in:
parent
ec6318b379
commit
da3791ad3d
|
@ -59940,6 +59940,7 @@
|
|||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@types/d3-format": "^1.3.0",
|
||||
"@types/d3-interpolate": "^1.3.1",
|
||||
"@types/d3-scale": "^2.1.1",
|
||||
|
@ -59993,6 +59994,50 @@
|
|||
"tinycolor2": "*"
|
||||
}
|
||||
},
|
||||
"packages/superset-ui-core/node_modules/@testing-library/react-hooks": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz",
|
||||
"integrity": "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"react-error-boundary": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.9.0 || ^17.0.0",
|
||||
"react": "^16.9.0 || ^17.0.0",
|
||||
"react-dom": "^16.9.0 || ^17.0.0",
|
||||
"react-test-renderer": "^16.9.0 || ^17.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"react-test-renderer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/superset-ui-core/node_modules/@testing-library/react-hooks/node_modules/react-error-boundary": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz",
|
||||
"integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.13.1"
|
||||
}
|
||||
},
|
||||
"packages/superset-ui-core/node_modules/@types/d3-time": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz",
|
||||
|
@ -61420,6 +61465,7 @@
|
|||
"@types/react-table": "^7.0.29",
|
||||
"classnames": "^2.3.2",
|
||||
"d3-array": "^2.4.0",
|
||||
"lodash": "^4.17.21",
|
||||
"match-sorter": "^6.3.0",
|
||||
"memoize-one": "^5.1.1",
|
||||
"react-table": "^7.6.3",
|
||||
|
@ -76247,6 +76293,7 @@
|
|||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"@testing-library/react-hooks": "*",
|
||||
"@types/d3-format": "^1.3.0",
|
||||
"@types/d3-interpolate": "^1.3.1",
|
||||
"@types/d3-scale": "^2.1.1",
|
||||
|
@ -76286,6 +76333,25 @@
|
|||
"whatwg-fetch": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@testing-library/react-hooks": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz",
|
||||
"integrity": "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"react-error-boundary": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-error-boundary": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz",
|
||||
"integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/d3-time": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz",
|
||||
|
@ -77286,6 +77352,7 @@
|
|||
"@types/react-table": "^7.0.29",
|
||||
"classnames": "^2.3.2",
|
||||
"d3-array": "^2.4.0",
|
||||
"lodash": "^4.17.21",
|
||||
"match-sorter": "^6.3.0",
|
||||
"memoize-one": "^5.1.1",
|
||||
"react-table": "^7.6.3",
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@types/d3-format": "^1.3.0",
|
||||
"@types/d3-interpolate": "^1.3.1",
|
||||
"@types/d3-scale": "^2.1.1",
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './useChangeEffect';
|
||||
export * from './useComponentDidMount';
|
||||
export * from './useComponentDidUpdate';
|
||||
export * from './useElementOnScreen';
|
||||
export * from './usePrevious';
|
||||
export * from './useTruncation';
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './useElementOnScreen';
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* 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 { renderHook } from '@testing-library/react-hooks';
|
||||
import React from 'react';
|
||||
import { useElementOnScreen } from './useElementOnScreen';
|
||||
|
||||
const observeMock = jest.fn();
|
||||
const unobserveMock = jest.fn();
|
||||
const IntersectionObserverMock = jest.fn();
|
||||
IntersectionObserverMock.prototype.observe = observeMock;
|
||||
IntersectionObserverMock.prototype.unobserve = unobserveMock;
|
||||
|
||||
beforeEach(() => {
|
||||
window.IntersectionObserver = IntersectionObserverMock;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
IntersectionObserverMock.mockClear();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('should return null and false on first render', () => {
|
||||
const hook = renderHook(() =>
|
||||
useElementOnScreen({ rootMargin: '-50px 0px 0px 0px' }),
|
||||
);
|
||||
expect(hook.result.current).toEqual([{ current: null }, false]);
|
||||
});
|
||||
|
||||
test('should return isSticky as true when intersectionRatio < 1', async () => {
|
||||
const hook = renderHook(() =>
|
||||
useElementOnScreen({ rootMargin: '-50px 0px 0px 0px' }),
|
||||
);
|
||||
const callback = IntersectionObserverMock.mock.calls[0][0];
|
||||
const callBack = callback([{ isIntersecting: true, intersectionRatio: 0.5 }]);
|
||||
const observer = new IntersectionObserverMock(callBack, {});
|
||||
const newDiv = document.createElement('div');
|
||||
observer.observe(newDiv);
|
||||
expect(hook.result.current[1]).toEqual(true);
|
||||
});
|
||||
|
||||
test('should return isSticky as false when intersectionRatio >= 1', async () => {
|
||||
const hook = renderHook(() =>
|
||||
useElementOnScreen({ rootMargin: '-50px 0px 0px 0px' }),
|
||||
);
|
||||
const callback = IntersectionObserverMock.mock.calls[0][0];
|
||||
const callBack = callback([{ isIntersecting: true, intersectionRatio: 1 }]);
|
||||
const observer = new IntersectionObserverMock(callBack, {});
|
||||
const newDiv = document.createElement('div');
|
||||
observer.observe(newDiv);
|
||||
expect(hook.result.current[1]).toEqual(false);
|
||||
});
|
||||
|
||||
test('should observe and unobserve element with IntersectionObserver', async () => {
|
||||
jest.spyOn(React, 'useRef').mockReturnValue({ current: 'test' });
|
||||
const options = { threshold: 0.5 };
|
||||
const { result, unmount } = renderHook(() => useElementOnScreen(options));
|
||||
const [elementRef] = result.current;
|
||||
|
||||
expect(IntersectionObserverMock).toHaveBeenCalledWith(
|
||||
expect.any(Function),
|
||||
options,
|
||||
);
|
||||
|
||||
expect(elementRef).not.toBe(null);
|
||||
expect(observeMock).toHaveBeenCalledWith(elementRef.current);
|
||||
|
||||
unmount();
|
||||
|
||||
expect(unobserveMock).toHaveBeenCalledWith(elementRef.current);
|
||||
});
|
||||
|
||||
test('should not observe an element if it is null', () => {
|
||||
jest.spyOn(React, 'useRef').mockReturnValue({ current: null });
|
||||
const options = {};
|
||||
const { result } = renderHook(() => useElementOnScreen(options));
|
||||
const [ref, isSticky] = result.current;
|
||||
expect(ref.current).toBe(null);
|
||||
expect(isSticky).toBe(false);
|
||||
|
||||
expect(observeMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should not unobserve the element if it is null', () => {
|
||||
jest.spyOn(React, 'useRef').mockReturnValue({ current: null });
|
||||
const options = {};
|
||||
const { result, unmount } = renderHook(() => useElementOnScreen(options));
|
||||
const [ref, isSticky] = result.current;
|
||||
|
||||
expect(ref.current).toBe(null);
|
||||
expect(isSticky).toBe(false);
|
||||
|
||||
unmount();
|
||||
|
||||
expect(unobserveMock).not.toHaveBeenCalled();
|
||||
});
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* 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 { renderHook } from '@testing-library/react-hooks';
|
||||
import React from 'react';
|
||||
import useCSSTextTruncation from './useCSSTextTruncation';
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('should be false by default', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useCSSTextTruncation<HTMLParagraphElement>(),
|
||||
);
|
||||
const [paragraphRef, isTruncated] = result.current;
|
||||
expect(paragraphRef.current).toBe(null);
|
||||
expect(isTruncated).toBe(false);
|
||||
});
|
||||
|
||||
test('should not truncate', () => {
|
||||
const ref = { current: document.createElement('p') };
|
||||
Object.defineProperty(ref.current, 'offsetWidth', { get: () => 100 });
|
||||
Object.defineProperty(ref.current, 'scrollWidth', { get: () => 50 });
|
||||
jest.spyOn(React, 'useRef').mockReturnValue({ current: ref.current });
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCSSTextTruncation<HTMLParagraphElement>(),
|
||||
);
|
||||
const [, isTruncated] = result.current;
|
||||
|
||||
expect(isTruncated).toBe(false);
|
||||
});
|
||||
|
||||
test('should truncate', () => {
|
||||
const ref = { current: document.createElement('p') };
|
||||
Object.defineProperty(ref.current, 'offsetWidth', { get: () => 50 });
|
||||
Object.defineProperty(ref.current, 'scrollWidth', { get: () => 100 });
|
||||
jest.spyOn(React, 'useRef').mockReturnValue({ current: ref.current });
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCSSTextTruncation<HTMLParagraphElement>(),
|
||||
);
|
||||
const [, isTruncated] = result.current;
|
||||
|
||||
expect(isTruncated).toBe(true);
|
||||
});
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* 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 { renderHook } from '@testing-library/react-hooks';
|
||||
import { RefObject } from 'react';
|
||||
import useChildElementTruncation from './useChildElementTruncation';
|
||||
|
||||
const genElements = (
|
||||
scrollWidth: number,
|
||||
clientWidth: number,
|
||||
offsetWidth: number | undefined,
|
||||
childNodes: any = [],
|
||||
) => {
|
||||
const elementRef: RefObject<Partial<HTMLElement>> = {
|
||||
current: { scrollWidth, clientWidth, childNodes },
|
||||
};
|
||||
const plusRef: RefObject<Partial<HTMLElement>> = {
|
||||
current: { offsetWidth },
|
||||
};
|
||||
return [elementRef, plusRef];
|
||||
};
|
||||
const useTruncation = (elementRef: any, plusRef: any) =>
|
||||
useChildElementTruncation(
|
||||
elementRef as RefObject<HTMLElement>,
|
||||
plusRef as RefObject<HTMLElement>,
|
||||
);
|
||||
|
||||
test('should return [0, false] when elementRef.current is not defined', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTruncation({ current: undefined }, { current: undefined }),
|
||||
);
|
||||
|
||||
expect(result.current).toEqual([0, false]);
|
||||
});
|
||||
|
||||
test('should not recompute when previousEffectInfo is the same as previous', () => {
|
||||
const elementRef = { current: document.createElement('div') };
|
||||
const plusRef = { current: document.createElement('div') };
|
||||
const { result, rerender } = renderHook(() =>
|
||||
useTruncation(elementRef, plusRef),
|
||||
);
|
||||
const previousEffectInfo = result.current;
|
||||
|
||||
rerender();
|
||||
|
||||
expect(result.current).toEqual(previousEffectInfo);
|
||||
});
|
||||
|
||||
test('should return [0, false] when there are no truncated/hidden elements', () => {
|
||||
const [elementRef, plusRef] = genElements(100, 100, 10);
|
||||
const { result } = renderHook(() => useTruncation(elementRef, plusRef));
|
||||
expect(result.current).toEqual([0, false]);
|
||||
});
|
||||
|
||||
test('should return [1, false] when there is only one truncated element', () => {
|
||||
const [elementRef, plusRef] = genElements(150, 100, 10);
|
||||
const { result } = renderHook(() => useTruncation(elementRef, plusRef));
|
||||
expect(result.current).toEqual([1, false]);
|
||||
});
|
||||
|
||||
test('should return [1, true] with one truncated and hidden elements', () => {
|
||||
const [elementRef, plusRef] = genElements(150, 100, 10, [
|
||||
{ offsetWidth: 150 } as HTMLElement,
|
||||
{ offsetWidth: 150 } as HTMLElement,
|
||||
]);
|
||||
const { result } = renderHook(() => useTruncation(elementRef, plusRef));
|
||||
expect(result.current).toEqual([1, true]);
|
||||
});
|
||||
|
||||
test('should return [2, true] with 2 truncated and hidden elements', () => {
|
||||
const [elementRef, plusRef] = genElements(150, 100, 10, [
|
||||
{ offsetWidth: 150 } as HTMLElement,
|
||||
{ offsetWidth: 150 } as HTMLElement,
|
||||
{ offsetWidth: 150 } as HTMLElement,
|
||||
]);
|
||||
const { result } = renderHook(() => useTruncation(elementRef, plusRef));
|
||||
expect(result.current).toEqual([2, true]);
|
||||
});
|
||||
|
||||
test('should return [1, true] with plusSize offsetWidth undefined', () => {
|
||||
const [elementRef, plusRef] = genElements(150, 100, undefined, [
|
||||
{ offsetWidth: 150 } as HTMLElement,
|
||||
{ offsetWidth: 150 } as HTMLElement,
|
||||
]);
|
||||
const { result } = renderHook(() => useTruncation(elementRef, plusRef));
|
||||
expect(result.current).toEqual([1, true]);
|
||||
});
|
|
@ -35,3 +35,4 @@ export * from './chart-composition';
|
|||
export * from './components';
|
||||
export * from './math-expression';
|
||||
export * from './ui-overrides';
|
||||
export * from './hooks';
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"@types/react-table": "^7.0.29",
|
||||
"classnames": "^2.3.2",
|
||||
"d3-array": "^2.4.0",
|
||||
"lodash": "^4.17.21",
|
||||
"match-sorter": "^6.3.0",
|
||||
"memoize-one": "^5.1.1",
|
||||
"react-table": "^7.6.3",
|
||||
|
|
|
@ -37,7 +37,8 @@ import {
|
|||
Row,
|
||||
} from 'react-table';
|
||||
import { matchSorter, rankings } from 'match-sorter';
|
||||
import { typedMemo } from '@superset-ui/core';
|
||||
import { typedMemo, usePrevious } from '@superset-ui/core';
|
||||
import { isEqual } from 'lodash';
|
||||
import GlobalFilter, { GlobalFilterProps } from './components/GlobalFilter';
|
||||
import SelectPageSize, {
|
||||
SelectPageSizeProps,
|
||||
|
@ -108,6 +109,8 @@ export default typedMemo(function DataTable<D extends object>({
|
|||
doSticky ? useSticky : [],
|
||||
hooks || [],
|
||||
].flat();
|
||||
const columnNames = Object.keys(data?.[0] || {});
|
||||
const previousColumnNames = usePrevious(columnNames);
|
||||
const resultsSize = serverPagination ? rowCount : data.length;
|
||||
const sortByRef = useRef([]); // cache initial `sortby` so sorting doesn't trigger page reset
|
||||
const pageSizeRef = useRef([initialPageSize, resultsSize]);
|
||||
|
@ -187,6 +190,7 @@ export default typedMemo(function DataTable<D extends object>({
|
|||
getTableSize: defaultGetTableSize,
|
||||
globalFilter: defaultGlobalFilter,
|
||||
sortTypes,
|
||||
autoResetSortBy: !isEqual(columnNames, previousColumnNames),
|
||||
...moreUseTableOptions,
|
||||
},
|
||||
...tableHooks,
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
*/
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { css, styled } from '@superset-ui/core';
|
||||
import { css, styled, usePrevious } from '@superset-ui/core';
|
||||
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import { areArraysShallowEqual } from 'src/reduxUtils';
|
||||
import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
|
||||
import {
|
||||
|
|
|
@ -28,8 +28,8 @@ import {
|
|||
styled,
|
||||
t,
|
||||
useTheme,
|
||||
usePrevious,
|
||||
} from '@superset-ui/core';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
|
||||
import {
|
||||
ISaveableDatasource,
|
||||
|
|
|
@ -30,9 +30,8 @@ import React, {
|
|||
ReactNode,
|
||||
} from 'react';
|
||||
import { Global } from '@emotion/react';
|
||||
import { css, t, useTheme } from '@superset-ui/core';
|
||||
import { css, t, useTheme, usePrevious } from '@superset-ui/core';
|
||||
import { useResizeDetector } from 'react-resize-detector';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import Badge from '../Badge';
|
||||
import Icons from '../Icons';
|
||||
import Button from '../Button';
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import { css, t, styled } from '@superset-ui/core';
|
||||
import { css, t, styled, useComponentDidMount } from '@superset-ui/core';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import { useComponentDidMount } from 'src/hooks/useComponentDidMount';
|
||||
import Icons from 'src/components/Icons';
|
||||
|
||||
export interface FaveStarProps {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
import { useToasts } from 'src/components/MessageToasts/withToasts';
|
||||
import { useComponentDidMount } from 'src/hooks/useComponentDidMount';
|
||||
import { useComponentDidMount } from '@superset-ui/core';
|
||||
|
||||
type FlashMessageType = 'info' | 'alert' | 'danger' | 'warning' | 'success';
|
||||
export type FlashMessage = [FlashMessageType, string];
|
||||
|
|
|
@ -17,9 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React, { useMemo, useRef } from 'react';
|
||||
import { styled } from '@superset-ui/core';
|
||||
import { styled, useTruncation } from '@superset-ui/core';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTruncation } from 'src/hooks/useTruncation';
|
||||
import CrossLinksTooltip from './CrossLinksTooltip';
|
||||
|
||||
export type CrossLinkProps = {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import {
|
||||
t,
|
||||
|
@ -28,6 +27,7 @@ import {
|
|||
FeatureFlag,
|
||||
isFeatureEnabled,
|
||||
getExtensionsRegistry,
|
||||
usePrevious,
|
||||
} from '@superset-ui/core';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { Switch } from 'src/components/Switch';
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { Tag as AntdTag } from 'antd';
|
||||
import { styled } from '@superset-ui/core';
|
||||
import { useCSSTextTruncation } from 'src/hooks/useTruncation';
|
||||
import { styled, useCSSTextTruncation } from '@superset-ui/core';
|
||||
import { Tooltip } from '../Tooltip';
|
||||
import { CustomTagProps } from './types';
|
||||
import { SELECT_ALL_VALUE } from './utils';
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
*/
|
||||
|
||||
import React, { ReactNode, useMemo, useRef } from 'react';
|
||||
import { styled, t } from '@superset-ui/core';
|
||||
import { useTruncation } from 'src/hooks/useTruncation';
|
||||
import { styled, t, useTruncation } from '@superset-ui/core';
|
||||
import { Tooltip } from '../Tooltip';
|
||||
|
||||
export type TruncatedListProps<ListItemType> = {
|
||||
|
|
|
@ -33,6 +33,7 @@ import {
|
|||
styled,
|
||||
t,
|
||||
useTheme,
|
||||
useElementOnScreen,
|
||||
} from '@superset-ui/core';
|
||||
import { Global } from '@emotion/react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
@ -56,7 +57,6 @@ import {
|
|||
setDirectPathToChild,
|
||||
setEditMode,
|
||||
} from 'src/dashboard/actions/dashboardState';
|
||||
import { useElementOnScreen } from 'src/hooks/useElementOnScreen';
|
||||
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
|
||||
import {
|
||||
deleteTopLevelTabs,
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
getCategoricalSchemeRegistry,
|
||||
isFeatureEnabled,
|
||||
SupersetClient,
|
||||
useComponentDidUpdate,
|
||||
} from '@superset-ui/core';
|
||||
import { ParentSize } from '@visx/responsive';
|
||||
import pick from 'lodash/pick';
|
||||
|
@ -48,7 +49,6 @@ import findTabIndexByComponentId from 'src/dashboard/util/findTabIndexByComponen
|
|||
import { setInScopeStatusOfFilters } from 'src/dashboard/actions/nativeFilters';
|
||||
import { dashboardInfoChanged } from 'src/dashboard/actions/dashboardInfo';
|
||||
import { setColorScheme } from 'src/dashboard/actions/dashboardState';
|
||||
import { useComponentDidUpdate } from 'src/hooks/useComponentDidUpdate/useComponentDidUpdate';
|
||||
import jsonStringify from 'json-stringify-pretty-compact';
|
||||
import { NATIVE_FILTER_DIVIDER_PREFIX } from '../nativeFilters/FiltersConfigModal/utils';
|
||||
import { findTabsWithChartsInScope } from '../nativeFilters/utils';
|
||||
|
|
|
@ -20,9 +20,13 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { uniqWith } from 'lodash';
|
||||
import cx from 'classnames';
|
||||
import { DataMaskStateWithId, Filters, styled } from '@superset-ui/core';
|
||||
import {
|
||||
DataMaskStateWithId,
|
||||
Filters,
|
||||
styled,
|
||||
usePrevious,
|
||||
} from '@superset-ui/core';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import { setDirectPathToChild } from 'src/dashboard/actions/dashboardState';
|
||||
import Badge from 'src/components/Badge';
|
||||
import DetailsPanelPopover from './DetailsPanel';
|
||||
|
|
|
@ -18,11 +18,16 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { styled, css, useTheme, getColumnLabel } from '@superset-ui/core';
|
||||
import {
|
||||
styled,
|
||||
css,
|
||||
useTheme,
|
||||
getColumnLabel,
|
||||
useCSSTextTruncation,
|
||||
} from '@superset-ui/core';
|
||||
import { CrossFilterIndicator } from 'src/dashboard/components/nativeFilters/selectors';
|
||||
import { Tag } from 'src/components';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import useCSSTextTruncation from 'src/hooks/useTruncation/useCSSTextTruncation';
|
||||
import { FilterBarOrientation } from 'src/dashboard/types';
|
||||
import { ellipsisCss } from './styles';
|
||||
|
||||
|
|
|
@ -18,9 +18,14 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { t, css, styled, useTheme } from '@superset-ui/core';
|
||||
import {
|
||||
t,
|
||||
css,
|
||||
styled,
|
||||
useTheme,
|
||||
useCSSTextTruncation,
|
||||
} from '@superset-ui/core';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import useCSSTextTruncation from 'src/hooks/useTruncation/useCSSTextTruncation';
|
||||
import { FilterBarOrientation } from 'src/dashboard/types';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { ellipsisCss } from './styles';
|
||||
|
|
|
@ -22,11 +22,10 @@ import {
|
|||
InPortal,
|
||||
OutPortal,
|
||||
} from 'react-reverse-portal';
|
||||
import { styled, SupersetTheme } from '@superset-ui/core';
|
||||
import { styled, SupersetTheme, truncationCSS } from '@superset-ui/core';
|
||||
import { FormItem as StyledFormItem, Form } from 'src/components/Form';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import { FilterBarOrientation } from 'src/dashboard/types';
|
||||
import { truncationCSS } from 'src/hooks/useTruncation';
|
||||
import { checkIsMissingRequiredValue } from '../utils';
|
||||
import FilterValue from './FilterValue';
|
||||
import { FilterCard } from '../../FilterCard';
|
||||
|
|
|
@ -17,12 +17,16 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { css, useTheme } from '@superset-ui/core';
|
||||
import {
|
||||
css,
|
||||
useTheme,
|
||||
useCSSTextTruncation,
|
||||
truncationCSS,
|
||||
} from '@superset-ui/core';
|
||||
import React from 'react';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import { FilterBarOrientation } from 'src/dashboard/types';
|
||||
import { useCSSTextTruncation, truncationCSS } from 'src/hooks/useTruncation';
|
||||
import { FilterDividerProps } from './types';
|
||||
|
||||
const VerticalDivider = ({ title, description }: FilterDividerProps) => (
|
||||
|
|
|
@ -27,9 +27,9 @@ import {
|
|||
DataMask,
|
||||
SLOW_DEBOUNCE,
|
||||
isNativeFilter,
|
||||
usePrevious,
|
||||
} from '@superset-ui/core';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import { updateDataMask, clearDataMask } from 'src/dataMask/actions';
|
||||
import { useImmer } from 'use-immer';
|
||||
import { isEmpty, isEqual, debounce } from 'lodash';
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
*/
|
||||
import React, { useCallback, useMemo, useRef } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { css, t, useTheme } from '@superset-ui/core';
|
||||
import { css, t, useTheme, useTruncation } from '@superset-ui/core';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { useTruncation } from 'src/hooks/useTruncation';
|
||||
import { setDirectPathToChild } from 'src/dashboard/actions/dashboardState';
|
||||
import {
|
||||
DependencyItem,
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
*/
|
||||
import React, { useRef } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { css, SupersetTheme, useTheme } from '@superset-ui/core';
|
||||
import { css, SupersetTheme, useTheme, useTruncation } from '@superset-ui/core';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { useTruncation } from 'src/hooks/useTruncation';
|
||||
import { RootState } from 'src/dashboard/types';
|
||||
import { Row, FilterName, InternalRow } from './Styles';
|
||||
import { FilterCardRowProps } from './types';
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React, { useMemo, useRef } from 'react';
|
||||
import { t } from '@superset-ui/core';
|
||||
import { useTruncation } from 'src/hooks/useTruncation';
|
||||
import { t, useTruncation } from '@superset-ui/core';
|
||||
import { useFilterScope } from './useFilterScope';
|
||||
import {
|
||||
Row,
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React, { useCallback, useState, useMemo, useEffect } from 'react';
|
||||
import { Column, ensureIsArray, t } from '@superset-ui/core';
|
||||
import { useChangeEffect } from 'src/hooks/useChangeEffect';
|
||||
import { Column, ensureIsArray, t, useChangeEffect } from '@superset-ui/core';
|
||||
import { Select, FormInstance } from 'src/components';
|
||||
import { useToasts } from 'src/components/MessageToasts/withToasts';
|
||||
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||
|
|
|
@ -18,10 +18,14 @@
|
|||
*/
|
||||
|
||||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { NativeFilterScope, styled, t } from '@superset-ui/core';
|
||||
import {
|
||||
NativeFilterScope,
|
||||
styled,
|
||||
t,
|
||||
useComponentDidUpdate,
|
||||
} from '@superset-ui/core';
|
||||
import { Radio } from 'src/components/Radio';
|
||||
import { AntdForm, Typography } from 'src/components';
|
||||
import { useComponentDidUpdate } from 'src/hooks/useComponentDidUpdate/useComponentDidUpdate';
|
||||
import { ScopingType } from './types';
|
||||
import ScopingTree from './ScopingTree';
|
||||
import { getDefaultScopeValue, isScopingAll } from './utils';
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { useEffect } from 'react';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import { NativeFilterType } from '@superset-ui/core';
|
||||
import { NativeFilterType, usePrevious } from '@superset-ui/core';
|
||||
import { FilterRemoval } from './types';
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,8 +22,12 @@ import {
|
|||
ControlType,
|
||||
ControlComponentProps as BaseControlComponentProps,
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { styled, JsonValue, QueryFormData } from '@superset-ui/core';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import {
|
||||
styled,
|
||||
JsonValue,
|
||||
QueryFormData,
|
||||
usePrevious,
|
||||
} from '@superset-ui/core';
|
||||
import ErrorBoundary from 'src/components/ErrorBoundary';
|
||||
import { ExploreActions } from 'src/explore/actions/exploreActions';
|
||||
import controlMap from './controls';
|
||||
|
|
|
@ -39,6 +39,7 @@ import {
|
|||
isDefined,
|
||||
JsonValue,
|
||||
NO_TIME_RANGE,
|
||||
usePrevious,
|
||||
} from '@superset-ui/core';
|
||||
import {
|
||||
ControlPanelSectionConfig,
|
||||
|
@ -59,7 +60,6 @@ import { PluginContext } from 'src/components/DynamicPlugins';
|
|||
import Loading from 'src/components/Loading';
|
||||
import Modal from 'src/components/Modal';
|
||||
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import { getSectionsToRender } from 'src/explore/controlUtils';
|
||||
import { ExploreActions } from 'src/explore/actions/exploreActions';
|
||||
import { ChartState, ExplorePageState } from 'src/explore/types';
|
||||
|
|
|
@ -21,15 +21,21 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { styled, t, css, useTheme, logging } from '@superset-ui/core';
|
||||
import {
|
||||
styled,
|
||||
t,
|
||||
css,
|
||||
useTheme,
|
||||
logging,
|
||||
useChangeEffect,
|
||||
useComponentDidMount,
|
||||
usePrevious,
|
||||
} from '@superset-ui/core';
|
||||
import { debounce, pick } from 'lodash';
|
||||
import { Resizable } from 're-resizable';
|
||||
import { useChangeEffect } from 'src/hooks/useChangeEffect';
|
||||
import { usePluginContext } from 'src/components/DynamicPlugins';
|
||||
import { Global } from '@emotion/react';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import { useComponentDidMount } from 'src/hooks/useComponentDidMount';
|
||||
import Icons from 'src/components/Icons';
|
||||
import {
|
||||
getItem,
|
||||
|
|
|
@ -17,10 +17,15 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { styled, css, t, useTheme } from '@superset-ui/core';
|
||||
import {
|
||||
styled,
|
||||
css,
|
||||
t,
|
||||
useTheme,
|
||||
useComponentDidUpdate,
|
||||
} from '@superset-ui/core';
|
||||
import Icons from 'src/components/Icons';
|
||||
import ControlHeader from 'src/explore/components/ControlHeader';
|
||||
import { useComponentDidUpdate } from 'src/hooks/useComponentDidUpdate';
|
||||
import { FormattingPopover } from './FormattingPopover';
|
||||
import {
|
||||
COMPARATOR,
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
useTheme,
|
||||
NO_TIME_RANGE,
|
||||
SupersetTheme,
|
||||
useCSSTextTruncation,
|
||||
} from '@superset-ui/core';
|
||||
import Button from 'src/components/Button';
|
||||
import ControlHeader from 'src/explore/components/ControlHeader';
|
||||
|
@ -35,7 +36,6 @@ import { Tooltip } from 'src/components/Tooltip';
|
|||
import { useDebouncedEffect } from 'src/explore/exploreUtils';
|
||||
import { SLOW_DEBOUNCE } from 'src/constants';
|
||||
import { noOp } from 'src/utils/common';
|
||||
import { useCSSTextTruncation } from 'src/hooks/useTruncation';
|
||||
import ControlPopover from '../ControlPopover/ControlPopover';
|
||||
|
||||
import { DateFilterControlProps, FrameType } from './types';
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ensureIsArray, t, useTheme } from '@superset-ui/core';
|
||||
import { ensureIsArray, t, useTheme, usePrevious } from '@superset-ui/core';
|
||||
import { isEqual } from 'lodash';
|
||||
import ControlHeader from 'src/explore/components/ControlHeader';
|
||||
import Icons from 'src/components/Icons';
|
||||
|
@ -28,7 +28,6 @@ import {
|
|||
HeaderContainer,
|
||||
LabelsContainer,
|
||||
} from 'src/explore/components/controls/OptionControls';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import columnType from './columnType';
|
||||
import MetricDefinitionValue from './MetricDefinitionValue';
|
||||
import AdhocMetric from './AdhocMetric';
|
||||
|
|
Loading…
Reference in New Issue