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

[Lens] Clean up operations code #43784

Merged
merged 15 commits into from
Aug 28, 2019
Merged
Show file tree
Hide file tree
Changes from 13 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
48 changes: 44 additions & 4 deletions x-pack/legacy/plugins/lens/public/app_plugin/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ interface State {
query: Query;
indexPatternTitles: string[];
persistedDoc?: Document;
localQueryBarState: {
query?: Query;
dateRange?: {
from: string;
to: string;
};
};
}

function isLocalStateDirty(
localState: State['localQueryBarState'],
query: Query,
dateRange: State['dateRange']
) {
return Boolean(
(localState.query && query && localState.query.query !== query.query) ||
(localState.dateRange && dateRange.fromDate !== localState.dateRange.from) ||
(localState.dateRange && dateRange.toDate !== localState.dateRange.to)
);
}

export function App({
Expand Down Expand Up @@ -57,6 +76,13 @@ export function App({
toDate: timeDefaults.to,
},
indexPatternTitles: [],
localQueryBarState: {
query: { query: '', language },
dateRange: {
from: timeDefaults.from,
to: timeDefaults.to,
},
},
});

const lastKnownDocRef = useRef<Document | undefined>(undefined);
Expand All @@ -72,6 +98,10 @@ export function App({
isLoading: false,
persistedDoc: doc,
query: doc.state.query,
localQueryBarState: {
...state.localQueryBarState,
query: doc.state.query,
},
indexPatternTitles: doc.state.datasourceMetaData.filterableIndexPatterns.map(
({ title }) => title
),
Expand Down Expand Up @@ -152,24 +182,34 @@ export function App({
<QueryBar
data-test-subj="lnsApp_queryBar"
screenTitle={'lens'}
onSubmit={({ dateRange, query }) => {
onSubmit={payload => {
const { dateRange, query } = payload;
setState({
...state,
dateRange: {
fromDate: dateRange.from,
toDate: dateRange.to,
},
query: query || state.query,
localQueryBarState: payload,
});
}}
onChange={localQueryBarState => {
setState({ ...state, localQueryBarState });
}}
isDirty={isLocalStateDirty(state.localQueryBarState, state.query, state.dateRange)}
appName={'lens'}
indexPatterns={state.indexPatternTitles}
store={store}
showDatePicker={true}
showQueryInput={true}
query={state.query}
dateRangeFrom={state.dateRange && state.dateRange.fromDate}
dateRangeTo={state.dateRange && state.dateRange.toDate}
query={state.localQueryBarState.query}
dateRangeFrom={
state.localQueryBarState.dateRange && state.localQueryBarState.dateRange.from
}
dateRangeTo={
state.localQueryBarState.dateRange && state.localQueryBarState.dateRange.to
}
uiSettings={uiSettings}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ $lnsPanelMinWidth: $euiSize * 18;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
overflow-x: hidden;
padding: $euiSize;
}

.lnsExpressionOutput > * {
flex: 1;
}

.lnsTitleInput {
width: 100%;
min-width: 100%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Storage } from 'ui/storage';
jest.mock('ui/new_platform');
jest.mock('../loader');
jest.mock('../state_helpers');
jest.mock('../operations');
jest.mock('../operations/operations');
flash1293 marked this conversation as resolved.
Show resolved Hide resolved

// Used by indexpattern plugin, which is a dependency of a dependency
jest.mock('ui/chrome');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@ import {
OperationType,
} from '../indexpattern';

import {
getAvailableOperationsByMetadata,
buildColumn,
operationDefinitionMap,
OperationDefinition,
} from '../operations';
import { getAvailableOperationsByMetadata, buildColumn, changeField } from '../operations';
import { PopoverEditor } from './popover_editor';
import { DragContextState, ChildDragDropProvider, DragDrop } from '../../drag_drop';
import { changeColumn, deleteColumn } from '../state_helpers';
Expand Down Expand Up @@ -130,9 +125,7 @@ export const IndexPatternDimensionPanel = memo(function IndexPatternDimensionPan
// If only the field has changed use the onFieldChange method on the operation to get the
// new column, otherwise use the regular buildColumn to get a new column.
const newColumn = hasFieldChanged
? (operationDefinitionMap[selectedColumn.operationType] as OperationDefinition<
IndexPatternColumn
>).onFieldChange(selectedColumn, currentIndexPattern, droppedItem.field)
? changeField(selectedColumn, currentIndexPattern, droppedItem.field)
: buildColumn({
columns: props.state.layers[props.layerId].columns,
indexPattern: currentIndexPattern,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
operationDefinitionMap,
getOperationDisplay,
buildColumn,
OperationDefinition,
changeField,
} from '../operations';
import { deleteColumn, changeColumn } from '../state_helpers';
import { FieldSelect } from './field_select';
Expand Down Expand Up @@ -284,14 +284,7 @@ export function PopoverEditor(props: PopoverEditorProps) {
) {
// If we just changed the field are not in an error state and the operation didn't change,
// we use the operations onFieldChange method to calculate the new column.
const operation = operationDefinitionMap[
choice.operationType
] as OperationDefinition<IndexPatternColumn>;
column = operation.onFieldChange(
selectedColumn,
currentIndexPattern,
fieldMap[choice.field]
);
column = changeField(selectedColumn, currentIndexPattern, fieldMap[choice.field]);
} else {
// Otherwise we'll use the buildColumn method to calculate a new column
column = buildColumn({
Expand Down Expand Up @@ -358,6 +351,7 @@ export function PopoverEditor(props: PopoverEditorProps) {
state={state}
setState={setState}
columnId={columnId}
currentColumn={state.layers[layerId].columns[columnId]}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems trivial to compute from the other props (layerId, columnId, state), so why pass it in separately?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment in the description about this was probably not super clear:

Adds currentColumn to param editor props to avoid plugging it out of the state object and casting it in every param editor

It's because of types - columns is a Record<string, IndexPatternColumn>, but inside of the param editor we need the specific type, TermsIndexPatternColumn, DateHistogramIndexPatternColumn and so on. We can cast it in there (that's how it was done before), but I try to get rid of casts where possible because they are a type mismatch waiting to happen. Doing it here is also implicitly casting the type to right one, but it's only a single place compared to the n places within in the param editor components, so less surface to get it wrong in the future.

storage={props.storage}
uiSettings={props.uiSettings}
layerId={layerId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ import { Storage } from 'ui/storage';
import {
DatasourceDimensionPanelProps,
DatasourceDataPanelProps,
DimensionPriority,
Operation,
DatasourceLayerPanelProps,
} from '../types';
import { Query } from '../../../../../../src/legacy/core_plugins/data/public/query';
import { getIndexPatterns } from './loader';
import { toExpression } from './to_expression';
import { IndexPatternDimensionPanel } from './dimension_panel';
Expand All @@ -29,70 +27,10 @@ import {

import { isDraggedField } from './utils';
import { LayerPanel } from './layerpanel';
import { IndexPatternColumn } from './operations';
import { Datasource } from '..';

export type OperationType = IndexPatternColumn['operationType'];

export type IndexPatternColumn =
| DateHistogramIndexPatternColumn
| TermsIndexPatternColumn
| SumIndexPatternColumn
| AvgIndexPatternColumn
| MinIndexPatternColumn
| MaxIndexPatternColumn
| CountIndexPatternColumn
| FilterRatioIndexPatternColumn;

export interface BaseIndexPatternColumn extends Operation {
// Private
operationType: OperationType;
suggestedPriority?: DimensionPriority;
}

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
type ParameterlessIndexPatternColumn<
TOperationType extends OperationType,
TBase extends BaseIndexPatternColumn = FieldBasedIndexPatternColumn
> = Omit<TBase, 'operationType'> & { operationType: TOperationType };

export interface FieldBasedIndexPatternColumn extends BaseIndexPatternColumn {
sourceField: string;
suggestedPriority?: DimensionPriority;
}

export interface DateHistogramIndexPatternColumn extends FieldBasedIndexPatternColumn {
operationType: 'date_histogram';
params: {
interval: string;
timeZone?: string;
};
}

export interface TermsIndexPatternColumn extends FieldBasedIndexPatternColumn {
operationType: 'terms';
params: {
size: number;
orderBy: { type: 'alphabetical' } | { type: 'column'; columnId: string };
orderDirection: 'asc' | 'desc';
};
}

export interface FilterRatioIndexPatternColumn extends BaseIndexPatternColumn {
operationType: 'filter_ratio';
params: {
numerator: Query;
denominator: Query;
};
}

export type CountIndexPatternColumn = ParameterlessIndexPatternColumn<
'count',
BaseIndexPatternColumn
>;
export type SumIndexPatternColumn = ParameterlessIndexPatternColumn<'sum'>;
export type AvgIndexPatternColumn = ParameterlessIndexPatternColumn<'avg'>;
export type MinIndexPatternColumn = ParameterlessIndexPatternColumn<'min'>;
export type MaxIndexPatternColumn = ParameterlessIndexPatternColumn<'max'>;
export { OperationType, IndexPatternColumn } from './operations';

export interface IndexPattern {
id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
IndexPatternPrivateState,
IndexPattern,
} from './indexpattern';
import { buildColumn, getOperationTypesForField } from './operations';
import { buildColumn, getOperationTypesForField } from './operations/operations';
import { hasField } from './utils';

function buildSuggestion({
Expand Down
Loading