Skip to content

Commit

Permalink
[Enhancement] Layer config: Add column validators (#1287)
Browse files Browse the repository at this point in the history
* Layer config: add column validaror
Signed-off-by: Shan He <heshan0131@gmail.com>

Co-authored-by: Ib Green <ib@unfolded.ai>
  • Loading branch information
heshan0131 and ibgreen committed Sep 30, 2020
1 parent e8fc1c5 commit d882ba0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 22 deletions.
8 changes: 5 additions & 3 deletions src/components/side-panel/layer-panel/layer-column-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {FormattedMessage} from 'localization';
import {createSelector} from 'reselect';

import {PanelLabel, SidePanelSection} from 'components/common/styled-components';
import FieldSelectorFactory from '../../common/field-selector';
import FieldSelectorFactory from 'components/common/field-selector';
import {validateColumn} from 'reducers/vis-state-merger';

const TopRow = styled.div`
display: flex;
Expand Down Expand Up @@ -91,6 +92,7 @@ function LayerColumnConfigFactory(ColumnSelector) {
{Object.keys(columns).map(key => (
<ColumnSelector
column={columns[key]}
columns={columns}
label={(columnLabels && columnLabels[key]) || key}
key={key}
allFields={fields}
Expand All @@ -108,7 +110,7 @@ function LayerColumnConfigFactory(ColumnSelector) {
}
ColumnSelectorFactory.deps = [FieldSelectorFactory];
function ColumnSelectorFactory(FieldSelector) {
const ColumnSelector = ({column, label, allFields, onSelect, fieldPairs}) => (
const ColumnSelector = ({column, columns, label, allFields, onSelect, fieldPairs}) => (
<ColumnRow className="layer-config__column__selector">
<ColumnName className="layer-config__column__name">
<PanelLabel>
Expand All @@ -119,7 +121,7 @@ function ColumnSelectorFactory(FieldSelector) {
<ColumnSelect className="layer-config__column__select">
<FieldSelector
suggested={fieldPairs}
error={!column.optional && !column.value}
error={!validateColumn(column, columns, allFields)}
fields={allFields}
value={column.value}
erasable={Boolean(column.optional)}
Expand Down
5 changes: 4 additions & 1 deletion src/layers/base-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,10 +511,13 @@ export default class Layer {
}

getLayerColumns() {
const columnValidators = this.columnValidators || {};
const required = this.requiredLayerColumns.reduce(
(accu, key) => ({
...accu,
[key]: {value: null, fieldIdx: -1}
[key]: columnValidators[key]
? {value: null, fieldIdx: -1, validator: columnValidators[key]}
: {value: null, fieldIdx: -1}
}),
{}
);
Expand Down
50 changes: 33 additions & 17 deletions src/reducers/vis-state-merger.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,28 +356,44 @@ export function mergeAnimationConfig(state, animation) {
* @return {null | Object} - validated columns or null
*/

export function validateSavedLayerColumns(fields, savedCols, emptyCols) {
const colFound = {};
// find actual column fieldIdx, in case it has changed
const allColFound = Object.keys(emptyCols).every(key => {
const saved = savedCols[key];
colFound[key] = {...emptyCols[key]};
export function validateSavedLayerColumns(fields, savedCols = {}, emptyCols) {
// Prepare columns for the validator
const columns = {};
for (const key of Object.keys(emptyCols)) {
columns[key] = {...emptyCols[key]};

// TODO: replace with new approach
const fieldIdx = fields.findIndex(({name}) => name === saved);
const saved = savedCols[key];
if (saved) {
const fieldIdx = fields.findIndex(({name}) => name === saved);

if (fieldIdx > -1) {
// update found columns
colFound[key].fieldIdx = fieldIdx;
colFound[key].value = saved;
return true;
if (fieldIdx > -1) {
// update found columns
columns[key].fieldIdx = fieldIdx;
columns[key].value = saved;
}
}
}

// if col is optional, allow null value
return emptyCols[key].optional || false;
});
// find actual column fieldIdx, in case it has changed
const allColFound = Object.keys(columns).every(key =>
validateColumn(columns[key], columns, fields)
);

if (allColFound) {
return columns;
}

return allColFound && colFound;
return null;
}

export function validateColumn(column, columns, allFields) {
if (column.optional || column.value) {
return true;
}
if (column.validator) {
return column.validator(column, columns, allFields);
}
return false;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion test/node/reducers/vis-state-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,7 @@ test('#visStateReducer -> UPDATE_VIS_DATA -> mergeFilters', t => {
metadata: {
id: 'smoothie',
label: 'smoothie and milkshake',
format: ''
format: ''
},
fields: expectedFields.map(f =>
f.name === mockFilter.name
Expand Down

0 comments on commit d882ba0

Please sign in to comment.