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

Plugin observations #6313

Closed
rashidkpc opened this issue Feb 23, 2016 · 6 comments
Closed

Plugin observations #6313

rashidkpc opened this issue Feb 23, 2016 · 6 comments
Labels
Feature:Plugins Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc

Comments

@rashidkpc
Copy link
Contributor

Creating this as a meta/discussion ticket about the plugin system. Leave comments below with your observations of creating plugins.

One of our goals is to create a very simple plugin layer with a minimal number of gotchas and code fluff. Eg, if 90% of apps need block-of-code-X that code should simply be included in the underlying plugin system, with an option to turn off the feature if needed.

For example, we expect 90% of applications to use our base style sheets, there should be no need to require them. In the case that advanced users do not wish to have those things auto loaded they can turn them off, but we should be optimizing for the usual case.

@rashidkpc
Copy link
Contributor Author

Adding visualizations that don't use the agg builder, but do fetch data

// When the expression updates
$scope.$watch('vis.params.expression', run);

// When the time filter changes
$scope.$listen(timefilter, 'fetch', run);

// When a filter is added to the filter bar?
$scope.$listen(queryFilter, 'fetch', run);

// When auto refresh happens
$scope.$on('courier:searchRefresh', run);

// When the refresh button or search button is clicked
???

There are at least 4 things visualizations need to listen for when they are created outside the agg builder model. There are then some places that it is unclear if its even possible to hook into, such as the refresh button on the visualization page.

I'd like to see the above code replaced with 2 events:

  • fetch: Kibana is informing the listener that the user has asked for new data to be fetched. This could be caused by the clicking of a search button, an auto refresh, updating of the time filter, whatever. This event should be broadcast on $rootScope so that plugins have the option of also broadcasting it.
  • render: This event should be used to inform listener that they should re-render existing data without fetching new data. Good examples would be resize events

@rashidkpc
Copy link
Contributor Author

injectVars: function (server, options) {
          var config = server.config();
          return {
            kbnIndex: config.get('kibana.index'),
            esShardTimeout: config.get('elasticsearch.shardTimeout'),
            esApiVersion: config.get('elasticsearch.apiVersion')
          };
        }

This block is required for most (all?) app plugins. The requirement for this leaks our internal implementation into plugins. We should just handle this. I'm actually not sure why the injectVars thing is required at all?

@trevan
Copy link
Contributor

trevan commented Feb 23, 2016

Modify UIExports (adding new items, removing new items) requires a full restart of the dev server. The autorestarts don't seem to handle it. To aid development, they should not require a full restart.

@trevan
Copy link
Contributor

trevan commented Feb 23, 2016

I use injectVars to get the config values from the node server into the UI. It would actually be nice for a plugin that isn't an app to add injectVars to the app it is modifying. Or, for a way to mark config values to be available in the UI.

@cjcenizal cjcenizal added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:Plugins and removed discuss labels Jan 9, 2017
@PhaedrusTheGreek
Copy link
Contributor

There seems to be a number of things unsupported for visualizations that do their own search. I think the first order of business should be to declare that we support vis plugins that do their own search.

From my recent experience developing this vis plugin:

Visualization Refresh

TLDR - you can't really do your own search without a bunch of tricks.

  1. Had to add the $scope.search listeners as mentioned above.

  2. Additionally I had to copy a hack from timelion that adds a listener for dashboard search bar events:

My vis:

<div refresh-hack ng-controller="TransformVisController" class="output-vis" ng-bind-html="vis.display">
</div>

My vis controller:

require('plugins/transform_vis/directives/refresh_hack');
...
    // From the hack directive
    $scope.$on('fetch', $scope.search);

directives/refresh_hack.js:

import $ from 'jquery';

const module = require('ui/modules').get('kibana/transform_vis', []);

module.directive('refreshHack', function () {
  return {
    restrict: 'A',
    link: function ($scope) {
      function broadcast() {
        $scope.$broadcast('fetch');
      }


      $scope.$on('$destroy', function () {
        $('[name="queryInput"]').unbind('submit', broadcast);
        $('[ng-click="fetch()"]').unbind('click', broadcast);
      });


      $('[name="queryInput"]').submit(broadcast);
      $('[ng-click="fetch()"]').click(broadcast);
    }
  };
});

Index Pattern Selection

TLDR - you can't really select an index pattern from the params controller without a couple tricks.

Currently your visualization can declare that it requiresSearch or not. This seems to encompass two things:

  • requiring an underlying search to execute, based on your selected schemas, etc.
  • Index selection / saved search selection.

My visualization does it's own search, but requires an index pattern selection, so I considered submitting a PR against master to allow this, but after discussing with @spalger , realized that it would be easier to implement my own index selection using the existing indexPattern service.

Additionally, should I have wanted to use the index pattern selection, I faced an additional problem - While I do require an index pattern, a saved search selection wouldn't make sense.

Proceeding to use the indexPattern service to select from existing patterns, I hit another snag. When a new pattern is selected by my params controller, I need to somehow indicate to Kibana that the selected pattern is now the pattern in context. The selectionService itself does not appear to provide that feature, but luckily, the params controller gave me access to the savedVis.searchSource, which has a set function.

$scope.savedVis.searchSource.set('index', indexPattern);

This method was very effective, and is bound to the UI / search bar as well. When I would switch from a time-based pattern to a non-time based pattern, the time search controls would come and go as expected.

As a final note to this problem, I also had to set the indexPattern in (params_controller)$scope.vis.indexPattern which is not the same object as (vis_controller)$scope.vis.indexPattern, which is understandable, so I had to add a listener in the vis controller for this change as well, or else the two would be out of sync.

@nreese
Copy link
Contributor

nreese commented Oct 2, 2020

Closing, no longer relevant with new platform

@nreese nreese closed this as completed Oct 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Plugins Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc
Projects
None yet
Development

No branches or pull requests

5 participants