diff --git a/src/legacy/core_plugins/data/public/filter/apply_filters/apply_filters_popover.tsx b/src/legacy/core_plugins/data/public/filter/apply_filters/apply_filters_popover.tsx index 6270dee72ab05..ab1ed8bfb9841 100644 --- a/src/legacy/core_plugins/data/public/filter/apply_filters/apply_filters_popover.tsx +++ b/src/legacy/core_plugins/data/public/filter/apply_filters/apply_filters_popover.tsx @@ -36,6 +36,7 @@ import React, { Component } from 'react'; import { IndexPattern } from '../../index_patterns'; import { getDisplayValueFromFilter } from '../filter_bar/filter_editor/lib/filter_editor_utils'; import { getFilterDisplayText } from '../filter_bar/filter_editor/lib/get_filter_display_text'; +import { mapAndFlattenFilters } from '../filter_manager/lib/map_and_flatten_filters'; interface Props { filters: Filter[]; @@ -70,9 +71,11 @@ export class ApplyFiltersPopover extends Component { return ''; } + const mappedFilters = mapAndFlattenFilters(this.props.filters); + const form = ( - {this.props.filters.map((filter, i) => ( + {mappedFilters.map((filter, i) => ( diff --git a/src/legacy/core_plugins/data/public/shim/legacy_module.ts b/src/legacy/core_plugins/data/public/shim/legacy_module.ts index 9ce35e6d2fa9e..0b5ca72599208 100644 --- a/src/legacy/core_plugins/data/public/shim/legacy_module.ts +++ b/src/legacy/core_plugins/data/public/shim/legacy_module.ts @@ -20,13 +20,11 @@ import { once } from 'lodash'; import { wrapInI18nContext } from 'ui/i18n'; -import { Filter } from '@kbn/es-query'; // @ts-ignore import { uiModules } from 'ui/modules'; import { npStart } from 'ui/new_platform'; import { FilterBar, ApplyFiltersPopover } from '../filter'; -import template from './apply_filter_directive.html'; // @ts-ignore import { mapAndFlattenFilters } from '../filter/filter_manager/lib/map_and_flatten_filters'; @@ -76,35 +74,53 @@ export const initLegacyModule = once((): void => { ['pluginDataStart', { watchDepth: 'reference' }], ]); }) - .directive('applyFiltersPopoverComponent', (reactDirective: any) => - reactDirective(wrapInI18nContext(ApplyFiltersPopover)) - ) .directive('applyFiltersPopover', () => { return { - template, restrict: 'E', - scope: { - filters: '=', - onCancel: '=', - onSubmit: '=', - indexPatterns: '=', - }, - link($scope: any) { - $scope.state = {}; - - // Each time the new filters change we want to rebuild (not just re-render) the "apply filters" - // popover, because it has to reset its state whenever the new filters change. Setting a `key` - // property on the component accomplishes this due to how React handles the `key` property. - $scope.$watch('filters', (filters: any) => { - const mappedFilters: Filter[] = mapAndFlattenFilters(filters); - $scope.state = { - filters: mappedFilters, - key: Date.now(), - }; - }); + template: '', + compile: (elem: any) => { + const child = document.createElement('apply-filters-popover-helper'); + + // Copy attributes to the child directive + for (const attr of elem[0].attributes) { + child.setAttribute(attr.name, attr.value); + } + + // Add a key attribute that will force a full rerender every time that + // a filter changes. + child.setAttribute('key', 'key'); + + // Append helper directive + elem.append(child); + + const linkFn = ($scope: any, _: any, $attr: any) => { + // Watch only for filter changes to update key. + $scope.$watch( + () => { + return $scope.$eval($attr.filters) || []; + }, + (newVal: any) => { + $scope.key = Date.now(); + }, + true + ); + }; + + return linkFn; }, }; - }); + }) + .directive('applyFiltersPopoverHelper', (reactDirective: any) => + reactDirective(wrapInI18nContext(ApplyFiltersPopover), [ + ['filters', { watchDepth: 'collection' }], + ['onCancel', { watchDepth: 'reference' }], + ['onSubmit', { watchDepth: 'reference' }], + ['indexPatterns', { watchDepth: 'collection' }], + + // Key is needed to trigger a full rerender of the component + 'key', + ]) + ); const module = uiModules.get('kibana/index_patterns'); let _service: any; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx index 488736da8456b..abf7b22a6e48c 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx @@ -422,19 +422,21 @@ export class DashboardAppController { }; $scope.onApplyFilters = filters => { - // All filters originated from one visualization. - const indexPatternId = filters[0].meta.index; - const indexPattern = _.find( - $scope.indexPatterns, - (p: IndexPattern) => p.id === indexPatternId - ); - if (indexPattern && indexPattern.timeFieldName) { - const { timeRangeFilter, restOfFilters } = extractTimeFilter( - indexPattern.timeFieldName, - filters + if (filters.length) { + // All filters originated from one visualization. + const indexPatternId = filters[0].meta.index; + const indexPattern = _.find( + $scope.indexPatterns, + (p: IndexPattern) => p.id === indexPatternId ); - queryFilter.addFilters(restOfFilters); - if (timeRangeFilter) changeTimeFilter(timefilter, timeRangeFilter); + if (indexPattern && indexPattern.timeFieldName) { + const { timeRangeFilter, restOfFilters } = extractTimeFilter( + indexPattern.timeFieldName, + filters + ); + queryFilter.addFilters(restOfFilters); + if (timeRangeFilter) changeTimeFilter(timefilter, timeRangeFilter); + } } $scope.appState.$newFilters = [];