From 7fb4cada432c3aff3b752dc906c8b77ef7e33e13 Mon Sep 17 00:00:00 2001 From: Igor D Date: Fri, 19 May 2023 20:27:30 +0300 Subject: [PATCH] [fix] Fix types for Typescript 4.8 (#2229) --- bindings/kepler.gl-jupyter/js/package.json | 1 + src/actions/src/actions.ts | 8 +++- src/actions/src/ui-state-actions.ts | 6 +-- src/components/src/editor/editor.tsx | 14 +++--- src/components/src/index.ts | 6 ++- src/components/src/map-container.tsx | 26 +++++------ src/components/src/map/map-control.tsx | 45 ++++++++++--------- src/components/src/map/map-draw-panel.tsx | 7 ++- src/components/src/map/map-popover.tsx | 4 +- src/components/src/side-panel.tsx | 16 +++---- .../src/side-panel/filter-manager.tsx | 11 +++-- .../src/side-panel/panel-header.tsx | 20 +++++---- .../src/side-panel/panel-toggle.tsx | 2 +- src/components/src/types.ts | 10 ++--- src/types/reducers.d.ts | 3 +- src/utils/src/index.ts | 2 +- 16 files changed, 100 insertions(+), 81 deletions(-) diff --git a/bindings/kepler.gl-jupyter/js/package.json b/bindings/kepler.gl-jupyter/js/package.json index d0add4497a..12362ed265 100644 --- a/bindings/kepler.gl-jupyter/js/package.json +++ b/bindings/kepler.gl-jupyter/js/package.json @@ -50,6 +50,7 @@ "eslint-plugin-babel": "^5.3.0", "eslint-plugin-prettier": "^3.0.1", "eslint-plugin-react": "~7.12.4", + "@jupyterlab/builder": "^4.0.0", "html-webpack-plugin": "^4.3.0", "react-dev-utils": "^10.2.1", "rimraf": "^2.6.1", diff --git a/src/actions/src/actions.ts b/src/actions/src/actions.ts index b520a31a0a..8d7159d2ba 100644 --- a/src/actions/src/actions.ts +++ b/src/actions/src/actions.ts @@ -30,7 +30,13 @@ import { ProtoDataset } from '@kepler.gl/types'; -export type ActionHandler any> = (...args: Parameters) => void; +type Handler = (...args: any) => any; + +export type ActionHandler = (...args: Parameters) => void; + +export type ActionHandlers = { + [K in keyof T]: ActionHandler; +}; /** * Add data to kepler.gl reducer, prepare map with preset configuration if config is passed. diff --git a/src/actions/src/ui-state-actions.ts b/src/actions/src/ui-state-actions.ts index 2fcba9193a..c8e4a2c345 100644 --- a/src/actions/src/ui-state-actions.ts +++ b/src/actions/src/ui-state-actions.ts @@ -25,7 +25,7 @@ import {ExportImage} from '@kepler.gl/constants'; /** TOGGLE_SIDE_PANEL */ export type ToggleSidePanelUpdaterAction = { - payload: string; + payload: string | null; }; /** * Toggle active side panel @@ -34,11 +34,11 @@ export type ToggleSidePanelUpdaterAction = { * @public */ export const toggleSidePanel: ( - id: string + id: string | null ) => Merge< ToggleSidePanelUpdaterAction, {type: typeof ActionTypes.TOGGLE_SIDE_PANEL} -> = createAction(ActionTypes.TOGGLE_SIDE_PANEL, (id: string) => ({payload: id})); +> = createAction(ActionTypes.TOGGLE_SIDE_PANEL, (id: string | null) => ({payload: id})); /** TOGGLE_MODAL */ export type ToggleModalUpdaterAction = { diff --git a/src/components/src/editor/editor.tsx b/src/components/src/editor/editor.tsx index 987afe9eff..ea4a1362f0 100644 --- a/src/components/src/editor/editor.tsx +++ b/src/components/src/editor/editor.tsx @@ -33,8 +33,8 @@ import { KeyEvent } from '@kepler.gl/constants'; import {Layer, EditorLayerUtils} from '@kepler.gl/layers'; -import {Filter, FeatureSelectionContext} from '@kepler.gl/types'; -import {Feature} from '@nebula.gl/edit-modes'; +import {Filter, FeatureSelectionContext, Feature} from '@kepler.gl/types'; +import {FeatureOf, Polygon} from '@nebula.gl/edit-modes'; import {Datasets} from '@kepler.gl/table'; const DECKGL_RENDER_LAYER = 'default-deckgl-overlay-wrapper'; @@ -53,12 +53,12 @@ interface EditorProps { datasets: Datasets; editor: {selectedFeature: Feature; mode: string; selectionContext?: FeatureSelectionContext}; index: number; - className: string; + className?: string; style: CSSProperties; - onSelect: (f: Feature | null) => void; + onSelect: (f: Feature | null) => any; onSetEditorMode: (m: any) => void; - onDeleteFeature: (f: Feature) => void; - onTogglePolygonFilter: (l: Layer, f: Feature) => void; + onDeleteFeature: (f: Feature) => any; + onTogglePolygonFilter: (l: Layer, f: Feature) => any; } export default function EditorFactory( @@ -163,7 +163,7 @@ export default function EditorFactory( {Boolean(rightClick) && selectedFeature && index === mapIndex ? ( } datasets={datasets} layers={availableLayers} currentFilter={currentFilter} diff --git a/src/components/src/index.ts b/src/components/src/index.ts index 8b430b67b3..26c8d005ee 100644 --- a/src/components/src/index.ts +++ b/src/components/src/index.ts @@ -42,7 +42,7 @@ export {default as KeplerGl, default, injectComponents, ContainerFactory, ERROR_ export {default as KeplerGlFactory, DEFAULT_KEPLER_GL_PROPS, getVisibleDatasets, mapFieldsSelector, plotContainerSelector} from './kepler-gl'; export {default as SidePanelFactory} from './side-panel'; export {default as PanelTitleFactory} from './side-panel/panel-title'; -export {default as MapContainerFactory} from './map-container'; +export {default as MapContainerFactory, Attribution} from './map-container'; export {default as MapsLayoutFactory} from './maps-layout'; export {default as BottomWidgetFactory} from './bottom-widget'; export {default as LayerAnimationControllerFactory} from './layer-animation-controller'; @@ -268,6 +268,10 @@ export type {LayerGroupColorPickerProps} from './side-panel/map-style-panel/map- export type {MapLegendPanelProps, MapLegendPanelFactoryDeps} from './map/map-legend-panel'; export type {FormatterDropdownProps} from './common/data-table/option-dropdown'; export type {LayerListProps, LayerListFactoryDeps} from './side-panel/layer-panel/layer-list'; +export type {MapContainerProps} from './map-container'; +export type {MapControlProps} from './map/map-control'; +export type {MapDrawPanelProps} from './map/map-draw-panel'; +export type {PanelHeaderProps} from './side-panel/panel-header'; export { Icons, diff --git a/src/components/src/map-container.tsx b/src/components/src/map-container.tsx index 20b2d4f177..a4d477a68b 100644 --- a/src/components/src/map-container.tsx +++ b/src/components/src/map-container.tsx @@ -202,11 +202,11 @@ const DatasetAttributions = ({ ); -export const Attribution = ({ - showMapboxLogo = true, - showOsmBasemapAttribution = false, - datasetAttributions -}) => { +export const Attribution: React.FC<{ + showMapboxLogo: boolean; + showOsmBasemapAttribution: boolean; + datasetAttributions: DatasetAttribution[]; +}> = ({showMapboxLogo = true, showOsmBasemapAttribution = false, datasetAttributions}) => { const isPalm = hasMobileWidth(breakPointValues); const memoizedComponents = useMemo(() => { @@ -268,7 +268,7 @@ MapContainerFactory.deps = [MapPopoverFactory, MapControlFactory, EditorFactory] type MapboxStyle = string | object | undefined; type PropSelector = Selector; -interface MapContainerProps { +export interface MapContainerProps { visState: VisState; mapState: MapState; mapControls: MapControls; @@ -310,9 +310,9 @@ interface MapContainerProps { } export default function MapContainerFactory( - MapPopover, - MapControl, - Editor + MapPopover: ReturnType, + MapControl: ReturnType, + Editor: ReturnType ): React.ComponentType { class MapContainer extends Component { displayName = 'MapContainer'; @@ -592,7 +592,7 @@ export default function MapContainerFactory( ? interactionConfig.tooltip.config.compareMode : false; - let pinnedPosition = {}; + let pinnedPosition = {x: 0, y: 0}; let layerPinnedProp: LayerHoverProp | null = null; if (pinned || clicked) { // project lnglat to screen so that tooltip follows the object on zoom @@ -903,11 +903,11 @@ export default function MapContainerFactory( availableLocales={LOCALE_CODES_ARRAY} dragRotate={mapState.dragRotate} isSplit={isSplit} - primary={primary} + primary={Boolean(primary)} isExport={isExport} layers={layers} layersToRender={layersToRender} - mapIndex={index} + mapIndex={index || 0} mapControls={mapControls} readOnly={this.props.readOnly} scale={mapState.scale || 1} @@ -941,7 +941,7 @@ export default function MapContainerFactory( {this._renderDeckOverlay(layersForDeck, {primaryMap: true})} {this._renderMapboxOverlays()} void; - onToggleSplitMap: () => void; + onToggleSplitMap: typeof MapStateActions.toggleSplitMap; onToggleSplitMapViewport: ({ isViewportSynced, isZoomLocked @@ -74,13 +75,15 @@ export type MapControlProps = { isViewportSynced: boolean; isZoomLocked: boolean; }) => void; + onMapToggleLayer: (layerId: string) => void; onToggleMapControl: (control: string) => void; onSetEditorMode: (mode: string) => void; onToggleEditorVisibility: () => void; top: number; - onSetLocale: () => void; + onSetLocale: typeof UIStateActions.setLocale; locale: string; - logoComponent: React.FC | React.ReactNode; + logoComponent?: React.FC | React.ReactNode; + isExport?: boolean; // optional mapState?: MapState; @@ -88,25 +91,25 @@ export type MapControlProps = { scale?: number; mapLayers?: {[key: string]: boolean}; editor: Editor; - actionComponents: React.FC[] | React.Component[]; + actionComponents?: React.ComponentType[]; mapHeight?: number; }; MapControlFactory.deps = [ - MapDrawPanelFactory, - Toggle3dButtonFactory, SplitMapButtonFactory, - MapLegendPanelFactory, + Toggle3dButtonFactory, LayerSelectorPanelFactory, + MapLegendPanelFactory, + MapDrawPanelFactory, LocalePanelFactory ]; function MapControlFactory( - MapDrawPanel: ReturnType, - Toggle3dButton: ReturnType, SplitMapButton: ReturnType, - MapLegendPanel: ReturnType, + Toggle3dButton: ReturnType, LayerSelectorPanel: ReturnType, + MapLegendPanel: ReturnType, + MapDrawPanel: ReturnType, LocalePanel: ReturnType ) { const DEFAULT_ACTIONS = [ @@ -118,23 +121,23 @@ function MapControlFactory( MapLegendPanel ]; - /** @type {import('./map-control').MapControl} */ - const MapControl: React.FC = React.memo(({actionComponents, ...props}) => { - return ( - - {actionComponents.map((ActionComponent, index) => ( - - ))} - - ); - }); + const MapControl: React.FC = React.memo( + ({actionComponents = DEFAULT_ACTIONS, ...props}) => { + return ( + + {actionComponents.map((ActionComponent, index) => ( + + ))} + + ); + } + ); MapControl.defaultProps = { isSplit: false, top: 0, mapIndex: 0, logoComponent: LegendLogo, - // @ts-expect-error actionComponents: DEFAULT_ACTIONS }; diff --git a/src/components/src/map/map-draw-panel.tsx b/src/components/src/map/map-draw-panel.tsx index a8b92e0098..551c0b4a1f 100644 --- a/src/components/src/map/map-draw-panel.tsx +++ b/src/components/src/map/map-draw-panel.tsx @@ -41,7 +41,10 @@ export type MapDrawPanelProps = { actionIcons: {[id: string]: React.ComponentType>}; }; -function MapDrawPanelFactory(MapControlTooltip, MapControlToolbar) { +function MapDrawPanelFactory( + MapControlTooltip: ReturnType, + MapControlToolbar: ReturnType +) { const defaultActionIcons = { visible: EyeSeen, hidden: EyeUnseen, @@ -50,7 +53,7 @@ function MapDrawPanelFactory(MapControlTooltip, MapControlToolbar) { innerPolygon: Polygon, rectangle: Rectangle }; - /** @type {import('./map-draw-panel').MapDrawPanelComponent} */ + const MapDrawPanel: React.FC = React.memo( ({ editor, diff --git a/src/components/src/map/map-popover.tsx b/src/components/src/map/map-popover.tsx index 918115d6c3..c65dc453e0 100644 --- a/src/components/src/map/map-popover.tsx +++ b/src/components/src/map/map-popover.tsx @@ -30,7 +30,7 @@ import {parseGeoJsonRawFeature} from '@kepler.gl/layers'; import {idToPolygonGeo, generateHashId} from '@kepler.gl/utils'; import {LAYER_TYPES} from '@kepler.gl/constants'; import {LayerHoverProp} from '@kepler.gl/reducers'; -import {Feature} from '@kepler.gl/types'; +import {Feature, FeatureSelectionContext} from '@kepler.gl/types'; const SELECTABLE_LAYERS: string[] = [LAYER_TYPES.hexagonId, LAYER_TYPES.geojson]; const MAX_WIDTH = 500; @@ -228,7 +228,7 @@ export type MapPopoverProps = { container?: HTMLElement | null; onClose: () => void; onSetFeatures: (features: Feature[]) => any; - setSelectedFeature: (feature: Feature, clickContext: object) => any; + setSelectedFeature: (feature: Feature | null, clickContext?: FeatureSelectionContext) => any; featureCollection?: { type: string; features: Feature[]; diff --git a/src/components/src/side-panel.tsx b/src/components/src/side-panel.tsx index 311bb26c87..4cb0d60580 100644 --- a/src/components/src/side-panel.tsx +++ b/src/components/src/side-panel.tsx @@ -45,7 +45,7 @@ import CustomPanelsFactory from './side-panel/custom-panel'; import styled from 'styled-components'; import get from 'lodash.get'; -import {SidePanelProps} from './types'; +import {SidePanelProps, SidePanelItem} from './types'; export const StyledSidePanelContent = styled.div` ${props => props.theme.sidePanelScrollBar}; @@ -101,7 +101,7 @@ export default function SidePanelFactory( }; // We should defined sidebar panels here but keeping them for backward compatible - const fullPanels = SIDEBAR_PANELS.map(component => ({ + const fullPanels: SidePanelItem[] = SIDEBAR_PANELS.map(component => ({ ...component, component: SIDEBAR_COMPONENTS[component.id], iconComponent: SIDEBAR_ICONS[component.id] @@ -110,7 +110,7 @@ export default function SidePanelFactory( const getCustomPanelProps = get(CustomPanels, ['defaultProps', 'getProps']) || (() => ({})); // eslint-disable-next-line max-statements - const SidePanel = (props: SidePanelProps) => { + const SidePanel: React.FC = (props: SidePanelProps) => { const { appName, appWebsite, @@ -123,7 +123,7 @@ export default function SidePanelFactory( layerClasses, layerOrder, interactionConfig, - panels, + panels = fullPanels, mapInfo, mapSaved, mapStateActions, @@ -181,7 +181,7 @@ export default function SidePanelFactory( () => (hasStorage && mapSaved ? onClickSaveAsToStorage : null), [hasStorage, mapSaved, onClickSaveAsToStorage] ); - const currentPanel = useMemo(() => panels.find(({id}) => id === activeSidePanel), [ + const currentPanel = useMemo(() => panels.find(({id}) => id === activeSidePanel) || null, [ activeSidePanel, panels ]); @@ -190,7 +190,6 @@ export default function SidePanelFactory( onClickShareMap ]); const customPanelProps = useMemo(() => getCustomPanelProps(props), [props]); - const PanelComponent = currentPanel?.component; return ( @@ -268,11 +267,6 @@ export default function SidePanelFactory( SidePanel.defaultProps = { panels: fullPanels, - sidebarComponents: SIDEBAR_COMPONENTS, - uiState: {}, - visStateActions: {}, - mapStyleActions: {}, - uiStateActions: {}, availableProviders: {}, mapInfo: {} }; diff --git a/src/components/src/side-panel/filter-manager.tsx b/src/components/src/side-panel/filter-manager.tsx index d59eabb964..b311caab39 100644 --- a/src/components/src/side-panel/filter-manager.tsx +++ b/src/components/src/side-panel/filter-manager.tsx @@ -27,7 +27,7 @@ import {FILTER_VIEW_TYPES, PANEL_VIEW_TOGGLES} from '@kepler.gl/constants'; import {Filter} from '@kepler.gl/types'; import {Layer} from '@kepler.gl/layers'; import {isSideFilter} from '@kepler.gl/utils'; -import {VisStateActions, ActionHandler, UIStateActions} from '@kepler.gl/actions'; +import {VisStateActions, ActionHandler, UIStateActions, ActionHandlers} from '@kepler.gl/actions'; import {Datasets} from '@kepler.gl/table'; import PanelViewListToggleFactory from './panel-view-list-toggle'; @@ -36,6 +36,9 @@ import AddFilterButtonFactory from './filter-panel/add-filter-button'; import DatasetSectionFactory from './layer-panel/dataset-section'; import {PanelMeta} from './common/types'; +type VisStateActionHandlers = ActionHandlers; +type UiStateActionHandlers = ActionHandlers; + type FilterManagerProps = { filters: Filter[]; datasets: Datasets; @@ -47,8 +50,8 @@ type FilterManagerProps = { panelMetadata: PanelMeta; panelListView: string; - visStateActions: typeof VisStateActions; - uiStateActions: typeof UIStateActions; + visStateActions: VisStateActionHandlers; + uiStateActions: UiStateActionHandlers; }; type FilterListProps = { @@ -60,7 +63,7 @@ type FilterListProps = { idx: number; }[]; isAnyFilterAnimating: boolean; - visStateActions: typeof VisStateActions; + visStateActions: VisStateActionHandlers; }; FilterManagerFactory.deps = [ diff --git a/src/components/src/side-panel/panel-header.tsx b/src/components/src/side-panel/panel-header.tsx index c02709ef9d..775daf4504 100644 --- a/src/components/src/side-panel/panel-header.tsx +++ b/src/components/src/side-panel/panel-header.tsx @@ -54,18 +54,20 @@ type PanelActionProps = { }; type PanelHeaderDropdownProps = { - id: string; items: ToolbarItemProps[]; show?: boolean; onClose: () => void; + id: string; +}; + +type LogoComponentProps = { + appName: string; + appWebsite: string; + version: string; }; type DropdownCallbacks = { - logoComponent?: React.ComponentType<{ - appName: string; - appWebsite: string; - version: string; - }>; + logoComponent?: React.FC | React.ComponentType; onExportImage: () => void; onExportData: () => void; onExportConfig?: () => void; @@ -89,7 +91,7 @@ type DropdownComponentProps = { items?: Item[]; } & DropdownCallbacks; -type PanelHeaderProps = { +export type PanelHeaderProps = { appName: string; appWebsite: string; version: string; @@ -225,7 +227,9 @@ export const SaveExportDropdownFactory = ( ) => { const dropdownItemsSelector = getDropdownItemsSelector(); - const SaveExportDropdown: React.FC = props => ( + const SaveExportDropdown: React.FC & { + defaultProps: {items: ToolbarItemProps[]}; + } = props => ( ; }; diff --git a/src/components/src/types.ts b/src/components/src/types.ts index c2a8f07c0e..bad0deba72 100644 --- a/src/components/src/types.ts +++ b/src/components/src/types.ts @@ -15,7 +15,7 @@ export type SidePanelItem = { id: string; label: string; iconComponent: ComponentType; - component?: ComponentType; + component: ComponentType; }; export type SidePanelProps = { @@ -29,18 +29,18 @@ export type SidePanelProps = { layerClasses: LayerClassesType; layerOrder: string[]; mapStyle: MapStyle; - onSaveMap?: () => void; + mapInfo: {title?: string; description?: string}; width: number; - mapInfo: {title: string; description: string}; datasets: Datasets; uiStateActions: typeof UIStateActions; visStateActions: typeof VisStateActions; mapStateActions: typeof MapStateActions; mapStyleActions: typeof MapStyleActions; uiState: UiState; - availableProviders: {hasShare: boolean; hasStorage: boolean}; + availableProviders: {[k: string]: {hasShare?: boolean; hasStorage?: boolean}}; mapSaved?: string | null; - panels: SidePanelItem[]; + panels?: SidePanelItem[]; + onSaveMap?: () => void; version: string; }; diff --git a/src/types/reducers.d.ts b/src/types/reducers.d.ts index 371bf5ced7..3936e646bd 100644 --- a/src/types/reducers.d.ts +++ b/src/types/reducers.d.ts @@ -168,6 +168,7 @@ export type Feature = { type: string; coordinates: any; }; + type?: string; }; export type FeatureSelectionContext = { rightClick: boolean; @@ -375,7 +376,7 @@ export type PanelListView = string; export type UiState = { readOnly: boolean; - activeSidePanel: string; + activeSidePanel: string | null; currentModal: string | null; datasetKeyToRemove: string | null; visibleDropdown: string | null; diff --git a/src/utils/src/index.ts b/src/utils/src/index.ts index e3fa519843..753f989699 100644 --- a/src/utils/src/index.ts +++ b/src/utils/src/index.ts @@ -68,7 +68,7 @@ export { formatNumber, getColumnFormatter } from './data-utils'; -export {getTimelineFromAnimationConfig, getTimelineFromFilter} from './time'; +export {getTimelineFromAnimationConfig, getTimelineFromFilter, SAMPLE_TIMELINE, TIMELINE_MODES} from './time'; export { datasetColorMaker,