Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,8 @@
* directly where they are needed.
*/

export { State } from 'ui/state_management/state';
// @ts-ignore
export { GlobalStateProvider } from 'ui/state_management/global_state';
// @ts-ignore
export { StateManagementConfigProvider } from 'ui/state_management/config_provider';

export { subscribeWithScope } from 'ui/utils/subscribe_with_scope';
// @ts-ignore
export { EventsProvider } from 'ui/events';
export { registerTimefilterWithGlobalStateFactory } from 'ui/timefilter/setup_router';
// @ts-ignore
export { KbnUrlProvider, RedirectWhenMissingProvider } from 'ui/url';
export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url';
export { KibanaParsedUrl } from 'ui/url/kibana_parsed_url';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular';
import { AppMountContext } from 'kibana/public';
import {
configureAppAngularModule,
GlobalStateProvider,
KbnUrlProvider,
RedirectWhenMissingProvider,
IPrivate,
PrivateProvider,
PromiseServiceCreator,
StateManagementConfigProvider,
} from '../legacy_imports';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../../plugins/navigation/public';
import {
Expand Down Expand Up @@ -87,55 +85,27 @@ function createLocalAngularModule(core: AppMountContext['core'], navigation: Nav
createLocalI18nModule();
createLocalPrivateModule();
createLocalPromiseModule();
createLocalConfigModule(core);
createLocalKbnUrlModule();
createLocalStateModule();
createLocalTopNavModule(navigation);

const visualizeAngularModule: IModule = angular.module(moduleName, [
...thirdPartyAngularDependencies,
'app/visualize/Config',
'app/visualize/I18n',
'app/visualize/Private',
'app/visualize/TopNav',
'app/visualize/State',
'app/visualize/KbnUrl',
'app/visualize/Promise',
]);
return visualizeAngularModule;
}

function createLocalStateModule() {
angular
.module('app/visualize/State', [
'app/visualize/Private',
'app/visualize/Config',
'app/visualize/KbnUrl',
'app/visualize/Promise',
])
.service('globalState', function(Private: IPrivate) {
return Private(GlobalStateProvider);
});
}

function createLocalKbnUrlModule() {
angular
.module('app/visualize/KbnUrl', ['app/visualize/Private', 'ngRoute'])
.service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider))
.service('redirectWhenMissing', (Private: IPrivate) => Private(RedirectWhenMissingProvider));
}

function createLocalConfigModule(core: AppMountContext['core']) {
angular
.module('app/visualize/Config', ['app/visualize/Private'])
.provider('stateManagementConfig', StateManagementConfigProvider)
.provider('config', () => {
return {
$get: () => ({
get: core.uiSettings.get.bind(core.uiSettings),
}),
};
});
}

function createLocalPromiseModule() {
angular.module('app/visualize/Promise', []).service('Promise', PromiseServiceCreator);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
refresh-interval="refreshInterval.value"
on-refresh-change="onRefreshChange"
show-save-query="showSaveQuery"
on-saved="onQuerySaved"
on-saved-query-updated="onSavedQueryUpdated"
on-saved="updateSavedQuery"
on-saved-query-updated="updateSavedQuery"
on-clear-saved-query="onClearSavedQuery"
>
</kbn-top-nav>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import angular from 'angular';
import _ from 'lodash';
import { Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import { i18n } from '@kbn/i18n';

import React from 'react';
Expand All @@ -29,13 +30,17 @@ import { VisualizeConstants } from '../visualize_constants';
import { getEditBreadcrumbs } from '../breadcrumbs';

import { addHelpMenuToAppChrome } from '../help_menu/help_menu_util';
import { FilterStateManager } from '../../../../../data/public';
import { unhashUrl } from '../../../../../../../plugins/kibana_utils/public';
import { kbnBaseUrl } from '../../../../../../../plugins/kibana_legacy/public';
import {
SavedObjectSaveModal,
showSaveModal,
} from '../../../../../../../plugins/saved_objects/public';
import {
esFilters,
connectToQueryState,
syncQueryStateWithUrl,
} from '../../../../../../../plugins/data/public';

import { initVisEditorDirective } from './visualization_editor';
import { initVisualizationDirective } from './visualization';
Expand Down Expand Up @@ -65,28 +70,21 @@ export function initEditorDirective(app, deps) {

function VisualizeAppController(
$scope,
$element,
$route,
$window,
$injector,
$timeout,
kbnUrl,
redirectWhenMissing,
Promise,
globalState,
config
kbnUrlStateStorage,
history
) {
const {
indexPatterns,
localStorage,
visualizeCapabilities,
share,
data: {
query: {
filterManager,
timefilter: { timefilter },
},
},
data: { query: queryService },
toastNotifications,
chrome,
getBasePath,
Expand All @@ -97,6 +95,17 @@ function VisualizeAppController(
setActiveUrl,
} = getServices();

const {
filterManager,
timefilter: { timefilter },
} = queryService;

// starts syncing `_g` portion of url with query services
const { stop: stopSyncingQueryServiceStateWithUrl } = syncQueryStateWithUrl(
queryService,
kbnUrlStateStorage
);

// Retrieve the resolved SavedVis instance.
const savedVis = $route.current.locals.savedVis;
const _applyVis = () => {
Expand Down Expand Up @@ -284,26 +293,24 @@ function VisualizeAppController(
linked: !!savedVis.savedSearchId,
};

const useHash = config.get('state:storeInSessionStorage');
const { stateContainer, stopStateSync } = useVisualizeAppState({
useHash,
stateDefaults,
kbnUrlStateStorage,
});

const filterStateManager = new FilterStateManager(
globalState,
() => {
// Temporary AppState replacement
return {
set filters(_filters) {
stateContainer.transitions.set('filters', _filters);
},
get filters() {
return stateContainer.getState().filters;
},
};
// sync initial app filters from state to filterManager
filterManager.setAppFilters(_.cloneDeep(stateContainer.getState().filters));
// setup syncing of app filters between appState and filterManager
const stopSyncingAppFilters = connectToQueryState(
queryService,
{
set: ({ filters }) => stateContainer.transitions.set('filters', filters),
get: () => ({ filters: stateContainer.getState().filters }),
state$: stateContainer.state$.pipe(map(state => ({ filters: state.filters }))),
},
filterManager
{
filters: esFilters.FilterStateStore.APP_STATE,
}
);

// The savedVis is pulled from elasticsearch, but the appState is pulled from the url, with the
Expand Down Expand Up @@ -335,6 +342,24 @@ function VisualizeAppController(
}
);

const updateSavedQueryFromUrl = savedQueryId => {
if (!savedQueryId) {
delete $scope.savedQuery;

return;
}

if ($scope.savedQuery && $scope.savedQuery.id === savedQueryId) {
return;
}

savedQueryService.getSavedQuery(savedQueryId).then(savedQuery => {
$scope.$evalAsync(() => {
$scope.updateSavedQuery(savedQuery);
});
});
};

function init() {
if (vis.indexPattern) {
$scope.indexPattern = vis.indexPattern;
Expand Down Expand Up @@ -388,14 +413,14 @@ function VisualizeAppController(
};

$scope.timeRange = timefilter.getTime();
$scope.opts = _.pick($scope, 'savedVis', 'isAddToDashMode');

const unsubscribeStateUpdates = stateContainer.subscribe(state => {
const newQuery = migrateLegacyQuery(state.query);
if (!_.isEqual(state.query, newQuery)) {
stateContainer.transitions.set('query', newQuery);
}
persistOnChange(state);
updateSavedQueryFromUrl(state.savedQuery);

// if the browser history was changed manually we need to reflect changes in the editor
if (!_.isEqual(vis.getState(), state.vis)) {
Expand All @@ -413,6 +438,9 @@ function VisualizeAppController(
$scope.$broadcast('render');
};

// update the query if savedQuery is stored
updateSavedQueryFromUrl(initialState.savedQuery);

const subscriptions = new Subscription();

subscriptions.add(
Expand All @@ -438,7 +466,7 @@ function VisualizeAppController(

// update the searchSource when query updates
$scope.fetch = function() {
const { query, filters, linked } = stateContainer.getState();
const { query, linked, filters } = stateContainer.getState();
$scope.query = query;
$scope.linked = linked;
savedVis.searchSource.setField('query', query);
Expand All @@ -451,7 +479,6 @@ function VisualizeAppController(
subscribeWithScope($scope, filterManager.getUpdates$(), {
next: () => {
$scope.filters = filterManager.getFilters();
$scope.globalFilters = filterManager.getGlobalFilters();
},
})
);
Expand All @@ -466,13 +493,14 @@ function VisualizeAppController(
$scope._handler.destroy();
}
savedVis.destroy();
filterStateManager.destroy();
subscriptions.unsubscribe();
$scope.vis.off('apply', _applyVis);

unsubscribePersisted();
unsubscribeStateUpdates();
stopStateSync();
stopSyncingQueryServiceStateWithUrl();
stopSyncingAppFilters();
});

$timeout(() => {
Expand Down Expand Up @@ -501,23 +529,14 @@ function VisualizeAppController(
});
};

$scope.onQuerySaved = savedQuery => {
$scope.savedQuery = savedQuery;
};

$scope.onSavedQueryUpdated = savedQuery => {
$scope.savedQuery = { ...savedQuery };
};

$scope.onClearSavedQuery = () => {
delete $scope.savedQuery;
stateContainer.transitions.removeSavedQuery(defaultQuery);
filterManager.setFilters(filterManager.getGlobalFilters());
$scope.fetch();
};

const updateStateFromSavedQuery = savedQuery => {
stateContainer.transitions.set('query', savedQuery.attributes.query);
stateContainer.transitions.updateFromSavedQuery(savedQuery);

const savedQueryFilters = savedQuery.attributes.filters || [];
const globalFilters = filterManager.getGlobalFilters();
Expand All @@ -532,25 +551,12 @@ function VisualizeAppController(
timefilter.setRefreshInterval(savedQuery.attributes.timefilter.refreshInterval);
}
}

$scope.fetch();
};

// update the query if savedQuery is stored
if (stateContainer.getState().savedQuery) {
savedQueryService.getSavedQuery(stateContainer.getState().savedQuery).then(savedQuery => {
$scope.$evalAsync(() => {
$scope.savedQuery = savedQuery;
});
});
}

$scope.$watch('savedQuery', newSavedQuery => {
if (!newSavedQuery) return;
stateContainer.transitions.set('savedQuery', newSavedQuery.id);

updateStateFromSavedQuery(newSavedQuery);
});
$scope.updateSavedQuery = savedQuery => {
$scope.savedQuery = savedQuery;
updateStateFromSavedQuery(savedQuery);
};

$scope.$watch('linked', linked => {
if (linked && !savedVis.savedSearchId) {
Expand Down Expand Up @@ -626,7 +632,10 @@ function VisualizeAppController(
savedVis.vis.title = savedVis.title;
savedVis.vis.description = savedVis.description;
} else {
kbnUrl.change(`${VisualizeConstants.EDIT_PATH}/{{id}}`, { id: savedVis.id });
history.replace({
...history.location,
pathname: `${VisualizeConstants.EDIT_PATH}/${savedVis.id}`,
});
}
}
});
Expand Down
Loading