Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[chore] Split out column mode config into separate component #2663

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import {
LayerColorRangeSelectorFactory,
ArcLayerColorSelectorFactory
} from './side-panel/layer-panel/layer-color-selector';
import LayerColumnModeConfigFactory from './side-panel/layer-panel/layer-column-mode-config';
import {
default as LayerColumnModeConfigFactory,
ColumnModeConfigFactory
} from './side-panel/layer-panel/layer-column-mode-config';
import {appInjector} from './container';

// Components
Expand Down Expand Up @@ -427,6 +430,7 @@ export {
ColorSelectorFactory,
LayerColorSelectorFactory,
LayerColumnModeConfigFactory,
ColumnModeConfigFactory,
LayerColorRangeSelectorFactory,
ArcLayerColorSelectorFactory
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import React, {useCallback, useMemo} from 'react';
import {LayerBaseConfig} from '@kepler.gl/layers';
import {
FieldPair,
Field,
ColumnPairs,
LayerColumns,
ColumnLabels,
Expand All @@ -21,7 +20,7 @@ import {SidePanelSection} from '../../common/styled-components';
export type LayerColumnConfigProps<FieldOption extends MinimalField> = {
columns: LayerColumns;
fields: FieldOption[];
assignColumnPairs: (key: string, pair: string) => LayerColumns;
assignColumnPairs: (key: string, pair: FieldPair) => LayerColumns;
assignColumn: (key: string, field: FieldOption) => LayerColumns;
updateLayerConfig: (newConfig: Partial<LayerBaseConfig>) => void;
updateLayerType?: (newType: string) => void;
Expand Down Expand Up @@ -54,7 +53,7 @@ function getValidFieldPairsSuggestionsForColumn(
LayerColumnConfigFactory.deps = [ColumnSelectorFactory];

function LayerColumnConfigFactory(ColumnSelector: ReturnType<typeof ColumnSelectorFactory>) {
const LayerColumnConfig: React.FC<LayerColumnConfigProps<Field>> = ({
const LayerColumnConfig: React.FC<LayerColumnConfigProps<MinimalField>> = ({
columnPairs,
fieldPairs,
columns,
Expand Down
172 changes: 118 additions & 54 deletions src/components/src/side-panel/layer-panel/layer-column-mode-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@
import LayerColumnConfigFactory from './layer-column-config';
import {FormattedMessage} from '@kepler.gl/localization';
import {assignColumnsByColumnMode, Layer, LayerInfoModal, LayerBaseConfig} from '@kepler.gl/layers';
import {SupportedColumnModes, FieldPair} from '@kepler.gl/types';
import {SupportedColumnMode, FieldPair, LayerColumns} from '@kepler.gl/types';

import {Help} from '../../common/icons';

LayerColumnModeConfigFactory.deps = [LayerColumnConfigFactory, PanelHeaderActionFactory];

const TopRow = styled.div`
display: flex;
justify-content: space-between;
Expand Down Expand Up @@ -78,32 +76,32 @@
}
`;

export type LayerColumnModeConfigProps<FieldOption extends MinimalField> = {
layer: Layer;
supportedColumnModes: SupportedColumnModes[] | null;
interface FieldOption extends MinimalField {}

export type ColumnModeConfigProps = {
supportedColumnModes: SupportedColumnMode[] | null;
selectedColumnMode?: string;
id: string;
layerConfig: LayerBaseConfig;
fields: FieldOption[];
fieldPairs?: FieldPair[];
openModal: (l: LayerInfoModal) => void;
updateLayerConfig: (config: Partial<LayerBaseConfig>) => void;
columns: LayerColumns;
renderColumnConfig: (mode: {key: string; label: string; columns: any}) => JSX.Element;
selectColumnMode: (mode: SupportedColumnMode) => void;
getHelpHandler?: (mode: SupportedColumnMode) => (() => void) | null;
};

function LayerColumnModeConfigFactory(
LayerColumnConfig: ReturnType<typeof LayerColumnConfigFactory>,
ColumnModeConfigFactory.deps = [PanelHeaderActionFactory];

export function ColumnModeConfigFactory(
PanelHeaderAction: ReturnType<typeof PanelHeaderActionFactory>
) {
const LayerColumnModeConfig: React.FC<LayerColumnModeConfigProps<any>> = ({
layer,
supportedColumnModes,
const ColumnModeConfig: React.FC<ColumnModeConfigProps> = ({
id,
layerConfig,
fields,
fieldPairs,
openModal,
updateLayerConfig
}: LayerColumnModeConfigProps<any>) => {
const {columns} = layerConfig;
supportedColumnModes,
selectedColumnMode,
columns,
renderColumnConfig,
selectColumnMode,
getHelpHandler = () => null
}: ColumnModeConfigProps) => {
const columnModes = useMemo(
() =>
supportedColumnModes
Expand All @@ -117,23 +115,11 @@
return {key, label, columns: allColumns};
})
: Object.keys(columns).length > 0
? [{key: 'default', label: undefined, columns}]
? [{key: 'default', label: '', columns}]
: [],
[supportedColumnModes, columns]
);

const handleSelectColumnMode = useCallback(
columnMode => {
const updatedColumns = assignColumnsByColumnMode({
columns,
supportedColumnModes,
columnMode
});

updateLayerConfig({columnMode, columns: updatedColumns});
},
[updateLayerConfig, columns, supportedColumnModes]
);
return (
<>
{columnModes.length > 0 ? (
Expand All @@ -147,19 +133,11 @@
</TopRow>
) : null}
<ConfigPanesContainer>
{columnModes.map(({key: columnMode, label, columns: cols}, i) => {
const columnPanel = (
<LayerColumnConfig
columnPairs={layer.columnPairs}
columns={cols}
assignColumnPairs={layer.assignColumnPairs.bind(layer)}
assignColumn={layer.assignColumn.bind(layer)}
columnLabels={layer.columnLabels}
fields={fields}
fieldPairs={fieldPairs}
updateLayerConfig={updateLayerConfig}
/>
);
{columnModes.map((modeConfig, i) => {
const columnPanel = renderColumnConfig(modeConfig);
const helpHandler = getHelpHandler(modeConfig);
const selectColumnModeHandler = () => selectColumnMode(modeConfig);
const {key: columnMode, label} = modeConfig;

return (
<Fragment key={columnMode}>
Expand All @@ -175,20 +153,19 @@
<Checkbox
type="radio"
name={`layer-${id}-input-modes`}
checked={layerConfig.columnMode === columnMode}
checked={selectedColumnMode === columnMode}
id={`${id}-input-column-${columnMode}`}
label={label}
secondary
onChange={() => handleSelectColumnMode(columnMode)}
onChange={selectColumnModeHandler}
/>
</PanelHeaderContent>
{layer.layerInfoModal?.[columnMode] ? (
{helpHandler ? (
<div className="interaction-panel__header__actions">
<PanelHeaderAction
id={`${id}-help-button`}
className="layer__help-button"
tooltip={'layerConfiguration.howTo'}
onClick={() => openModal(layer.layerInfoModal?.[columnMode])}
onClick={helpHandler}
IconComponent={Help}
/>
</div>
Expand All @@ -209,6 +186,93 @@
);
};

return ColumnModeConfig;
}

export type LayerColumnModeConfigProps = {
layer: Layer;
layerConfig: LayerBaseConfig;
supportedColumnModes: SupportedColumnMode[] | null;
id: string;
fields: FieldOption[];
fieldPairs?: FieldPair[];
openModal: (l: LayerInfoModal) => void;
updateLayerConfig: (config: Partial<LayerBaseConfig>) => void;
};

LayerColumnModeConfigFactory.deps = [LayerColumnConfigFactory, ColumnModeConfigFactory];

function LayerColumnModeConfigFactory(
LayerColumnConfig: ReturnType<typeof LayerColumnConfigFactory>,
ColumnModeConfig: ReturnType<typeof ColumnModeConfigFactory>
) {
const LayerColumnModeConfig = ({
id,
layer,
supportedColumnModes,
layerConfig,
fields,
fieldPairs,
openModal,
updateLayerConfig
}: LayerColumnModeConfigProps) => {
const {columns} = layerConfig;

const selectColumnMode = useCallback(
({key: columnMode}) => {
const updatedColumns = assignColumnsByColumnMode({
columns,
supportedColumnModes,
columnMode
});

updateLayerConfig({columnMode, columns: updatedColumns});
},
[updateLayerConfig, columns, supportedColumnModes]
);

const renderColumnConfig = useCallback(
({key: columnMode, label, columns: cols}) => (

Check warning on line 235 in src/components/src/side-panel/layer-panel/layer-column-mode-config.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

'columnMode' is defined but never used

Check warning on line 235 in src/components/src/side-panel/layer-panel/layer-column-mode-config.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

'label' is defined but never used
<LayerColumnConfig
columnPairs={layer.columnPairs}
columns={cols}
assignColumnPairs={layer.assignColumnPairs.bind(layer)}
assignColumn={
layer.assignColumn.bind(layer) as (key: string, field: FieldOption) => LayerColumns
}
columnLabels={layer.columnLabels}
fields={fields}
fieldPairs={fieldPairs}
updateLayerConfig={updateLayerConfig}
/>
),
[layer, updateLayerConfig, fieldPairs, fields]
);

const getHelpHandler = useCallback(
({key: columnMode}) => {
const modal = layer.layerInfoModal?.[columnMode];
if (modal) {
return () => openModal(modal);
}
return null;
},
[layer, openModal]
);

return (
<ColumnModeConfig
id={id}
supportedColumnModes={supportedColumnModes}
selectedColumnMode={layerConfig.columnMode}
columns={columns}
selectColumnMode={selectColumnMode}
renderColumnConfig={renderColumnConfig}
getHelpHandler={getHelpHandler}
/>
);
};

return LayerColumnModeConfig;
}

Expand Down
15 changes: 8 additions & 7 deletions src/layers/src/base-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
LayerColumn,
ColumnPairs,
ColumnLabels,
SupportedColumnModes
SupportedColumnMode,
FieldPair
} from '@kepler.gl/types';
import {KeplerTable, Datasets, GpuFilter} from '@kepler.gl/table';

Expand Down Expand Up @@ -390,7 +391,7 @@
/**
* Returns which column modes this layer supports
*/
get supportedColumnModes(): SupportedColumnModes[] | null {
get supportedColumnModes(): SupportedColumnMode[] | null {
return null;
}

Expand Down Expand Up @@ -438,10 +439,10 @@
return null;
}

return this.getAllPossibleColumnParis(requiredColumns);
return this.getAllPossibleColumnPairs(requiredColumns);
}

static getAllPossibleColumnParis(requiredColumns) {
static getAllPossibleColumnPairs(requiredColumns) {
// for multiple matched field for one required column, return multiple
// combinations, e. g. if column a has 2 matched, column b has 3 matched
// 6 possible column pairs will be returned
Expand Down Expand Up @@ -571,9 +572,9 @@
* Assign a field pair to column config, return column config
* @param key - Column Key
* @param pair - field Pair
* @returns {object} - Column config
* @returns Column config
*/
assignColumnPairs(key: string, pair: string): LayerColumns {
assignColumnPairs(key: string, pair: FieldPair): LayerColumns {
if (!this.columnPairs || !this.columnPairs?.[key]) {
// should not end in this state
return this.config.columns;
Expand Down Expand Up @@ -633,8 +634,8 @@
getHoverData(
object: any,
dataContainer: DataContainerInterface,
fields?: Field[],

Check warning on line 637 in src/layers/src/base-layer.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'fields' is defined but never used
animationConfig?: AnimationConfig

Check warning on line 638 in src/layers/src/base-layer.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'animationConfig' is defined but never used
): any {
if (!object) {
return null;
Expand Down Expand Up @@ -931,7 +932,7 @@
const {columns} = this.config;
return (
columns &&
Object.values(columns).every(column => {
Object.values(columns).every((column?: LayerColumn) => {
return Boolean(column && (column.optional || (column.value && column.fieldIdx > -1)));
})
);
Expand Down
6 changes: 3 additions & 3 deletions src/layers/src/layer-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import * as arrow from 'apache-arrow';
import {Feature, BBox} from 'geojson';
import {Field, FieldPair, SupportedColumnModes, LayerColumns} from '@kepler.gl/types';
import {Field, FieldPair, SupportedColumnMode, LayerColumns} from '@kepler.gl/types';
import {DataContainerInterface} from '@kepler.gl/utils';
import {
getBinaryGeometriesFromArrow,
Expand Down Expand Up @@ -135,7 +135,7 @@ export function getHoveredObjectFromArrow(
* find requiredColumns of supported column mode based on column mode
*/
export function getColumnModeRequiredColumns(
supportedColumnModes: SupportedColumnModes[] | null,
supportedColumnModes: SupportedColumnMode[] | null,
columnMode?: string
): string[] | undefined {
return supportedColumnModes?.find(({key}) => key === columnMode)?.requiredColumns;
Expand All @@ -150,7 +150,7 @@ export function assignColumnsByColumnMode({
columnMode
}: {
columns: LayerColumns;
supportedColumnModes: SupportedColumnModes[] | null;
supportedColumnModes: SupportedColumnMode[] | null;
columnMode: string | undefined;
}): LayerColumns {
const requiredColumns = getColumnModeRequiredColumns(supportedColumnModes, columnMode);
Expand Down
3 changes: 2 additions & 1 deletion src/types/layers.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,12 @@ export type EnhancedFieldPair = {
pair: FieldPair['pair'];
};

export type SupportedColumnModes = {
export type SupportedColumnMode = {
key: string;
label: string;
requiredColumns?: string[];
optionalColumns?: string[];
hasHelp?: boolean;
};

export type LayerColorConfig = {
Expand Down
8 changes: 4 additions & 4 deletions test/browser/layer-tests/base-layer-sepcs.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ test('#AggregationLayer -> updateLayerDomain', t => {
t.end();
});

test('#BaseLayer -> getAllPossibleColumnParis', t => {
test('#BaseLayer -> getAllPossibleColumnPairs', t => {
const columnes1 = {
a: [1, 2],
b: [3, 4]
Expand All @@ -124,8 +124,8 @@ test('#BaseLayer -> getAllPossibleColumnParis', t => {
const columnes3 = {
a: [1]
};
t.equal(Layer.getAllPossibleColumnParis(columnes1).length, 4, 'should find 4 pairs');
t.equal(Layer.getAllPossibleColumnParis(columnes2).length, 2, 'should find 4 pairs');
t.equal(Layer.getAllPossibleColumnParis(columnes3).length, 1, 'should find 4 pairs');
t.equal(Layer.getAllPossibleColumnPairs(columnes1).length, 4, 'should find 4 pairs');
t.equal(Layer.getAllPossibleColumnPairs(columnes2).length, 2, 'should find 4 pairs');
t.equal(Layer.getAllPossibleColumnPairs(columnes3).length, 1, 'should find 4 pairs');
t.end();
});
Loading