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

Management - New platform api #52579

Merged
merged 61 commits into from
Jan 8, 2020

Conversation

mattkime
Copy link
Contributor

@mattkime mattkime commented Dec 9, 2019

Summary

Addresses #51540

Implements Kibana platform management api along side the legacy management api, as documented here - #43631

but with the following modifications

  • Management Section getAvailable has been removed. It depends upon the capabilities api but this is an incomplete solution for determining whether a given management app should be displayed. ManagementApp will provide enable and disable methods which plugins can use as appropriate. getEnabledApps replaces it, which filters on enabled and sorts on order.
  • The mount function for ManagementApp will provide a setBreadcrumbs function available via the params argument. It provides core.chrome.setBreadcrumbs functionality but provides the top level breadcrumb.

Implementation note - Each management section is registered as a top level app inside a ui chrome (the management sidebar) rather than a single management app with extensions.

Checklist

Use strikethroughs to remove checklist items you don't feel are applicable to this PR.

For maintainers

Dev Docs

Management API for Kibana Platform

Management API for Kibana Platform implemented. Demonstration code available at test/plugin_functional/plugins/management_test_plugin/public/plugin.tsx

@kibanamachine
Copy link
Contributor

💔 Build Failed

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@elastic elastic deleted a comment from elasticmachine Dec 21, 2019
@mattkime mattkime requested a review from a team as a code owner January 7, 2020 05:16
euiIconType: 'logoElasticsearch',
});

return {
Copy link
Member

Choose a reason for hiding this comment

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

Will the NP Management API offer an equivalent to the LP deregister function? Security uses this today to hide the security section if Security becomes disabled, either via license change, or ES config change. /cc @azasypkin

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ManagementApp provides .disable() and .enable() for similar functionality.

Copy link
Member

@legrego legrego left a comment

Choose a reason for hiding this comment

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

Spaces changes LGTM

Copy link
Contributor

@ryankeairns ryankeairns left a comment

Choose a reason for hiding this comment

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

LGTM for design. The hard-coded pixel values have been removed; use of _index.scss files looks good.

@streamich streamich self-requested a review January 7, 2020 16:45
Copy link
Contributor

@streamich streamich left a comment

Choose a reason for hiding this comment

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

LGTM. Ran on Mac/Chrome.

Added few questions and optional comments.

Also, if section does not have an icon it seems to be shifted left:

image

It is a minor thing, but since icon is optional, maybe we want to left-align the sections without icons with the rest.

@@ -0,0 +1,204 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

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

In this /components folder would be nice to have each component in its own folder.

Comment on lines 29 to 31
constructor() {
this.sections = [];
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems constructor is not doing anything.

Comment on lines +68 to +72
private sharedInterface = {
getSection: this.getSection.bind(this),
getSectionsEnabled: this.getSectionsEnabled.bind(this),
getAllSections: this.getAllSections.bind(this),
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe these functions could be defined here directly.

  private sharedInterface = {
    getSection: (sectionId: ManagementSection['id']) =>
      this.sections.find(section => section.id === sectionId),
    getSectionsEnabled: () =>
      this.sections
        .filter(section => section.getAppsEnabled().length > 0)
        .sort((a, b) => a.order - b.order),
    getAllSections: () => this.sections,
  };

getAllSections: this.getAllSections.bind(this),
};

public setup = (
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious, why is setup defined as instance member instead of a method?

Suggested change
public setup = (
public setup(

};
};

public start = (navigateToApp: CoreStart['application']['navigateToApp']) => ({
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
public start = (navigateToApp: CoreStart['application']['navigateToApp']) => ({
public start(navigateToApp: CoreStart['application']['navigateToApp']) => ({

mobileTitle={this.renderMobileTitle()}
isOpenOnMobile={this.state.isSideNavOpenOnMobile}
toggleOpenOnMobile={this.toggleOpenOnMobile}
// @ts-ignore
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment seems not necessary.


const sectionVisible = (section: LegacySection | LegacyApp) => !section.disabled && section.visible;

export const sideNavItems = (sections: ManagementSection[], selectedId: string) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
export const sideNavItems = (sections: ManagementSection[], selectedId: string) =>
const sideNavItems = (sections: ManagementSection[], selectedId: string) =>

@@ -22,7 +22,7 @@ import { IndexedArray } from '../../../../legacy/ui/public/indexed_array';

const listeners = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious, why listerners are defined at module scope instead of being a member of LegacyManagementSection instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No particular reason. I'd prefer to leave it alone since this pr doesn't modify that file and the legacy code will be removed soon.

}

export type ManagementSectionMount = (
params: ManagementAppMountParams
Copy link
Contributor

@streamich streamich Jan 8, 2020

Choose a reason for hiding this comment

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

From the RFC my understanding was that Management app would use core's context containers, i.e. this function would have initial context argument:

Suggested change
params: ManagementAppMountParams
context, params: ManagementAppMountParams

Here is the RFC example.

And it would be implement like in this example.

But since the RFC context containers were deprecated and platform team said they will replace them by the Binder Service. Not sure what the status is on the binder service, and if there was a discussion to use the binder service here instead. Is it planned to be used here?

image

Currently I understand the plugins using Management app should instead use core.getStartServices() method to receive the start core and plugins?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps we should have a conversation with @joshdover about this. I've been confused about the purpose of context containers and I'm therefore uncertain of anything we're discussing in relationship to them.

Let's discuss via slack or zoom since I think we should even up on needs / expectations before talking interfaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

spoke with @streamich and his questions are mainly regarding what the platform team is providing rather than this implementation.

getSections={getSections}
selectedId={id}
legacySections={getLegacyManagementSections().items}
mountedCallback={async element => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
mountedCallback={async element => {
onMount={async element => {

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, maybe instead of handling mount/unmount here, the <ManagementChrome> component could receive the mount function and handle the mount/unmount internally?

<ManagementChrome
  mount={() => mount({
                basePath,
                element,
                setBreadcrumbs,
              })}
/>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've left this alone as my attempt at this didn't simplify things. I kind of like keeping ManagementChrome dumb, at least its a very simple separation of concerns.

kibana-app-arch automation moved this from In progress to Review in progress Jan 8, 2020
@lizozom
Copy link
Contributor

lizozom commented Jan 8, 2020

@streamich about the icon suggestion - I do think that it would be better to have a fallback icon for sections without an icon. @elastic/kibana-design

Copy link
Contributor

@lizozom lizozom left a comment

Choose a reason for hiding this comment

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

The test plugin is a great addition!

It would have been nice if this PR used ManagementChrome in core_plugins already, but I assume this can be done in a follow up PR.

I also support most of @streamich comments.

Otherwise, tested on Ubuntu \ Chrome and LGTM.

@mattkime
Copy link
Contributor Author

mattkime commented Jan 8, 2020

@streamich regarding alignment without an icon - that strikes me as an EUI issue.

@cchaos
Copy link
Contributor

cchaos commented Jan 8, 2020

regarding alignment without an icon - that strikes me as an EUI issue.

It's not an EUI issue, as we do allow the list to have no icons and therefore needs to be fully left aligned.

I do think that it would be better to have a fallback icon for sections without an icon.

Simply use the empty icon type and the section will align properly without showing a default/random icon.

@mattkime mattkime requested a review from a team as a code owner January 8, 2020 21:55
@mattkime mattkime merged commit 9282f19 into elastic:master Jan 8, 2020
kibana-app-arch automation moved this from Review in progress to Done in 7.6 Jan 8, 2020
mattkime added a commit to mattkime/kibana that referenced this pull request Jan 9, 2020
* implement management new platform api
mattkime added a commit that referenced this pull request Jan 9, 2020
* implement management new platform api
gmmorris added a commit to gmmorris/kibana that referenced this pull request Jan 9, 2020
* master: (23 commits)
  [Vis: Default editor] Reactify the timelion editor (elastic#52990)
  [Discover] fix histogram min interval (elastic#53979)
  [Telemetry] [Monitoring] Only retry fetching usage once monito… (elastic#54309)
  [docs][APM] Add runtime index config documentation (elastic#53907)
  [SIEM] Detection engine timeline (elastic#53783)
  Filter scripted fields preview field list to source fields (elastic#53826)
  Management - New platform api (elastic#52579)
  Reset region and Account when switching inventory (elastic#54287)
  [SIEM] [Case] Case workflow api schema (elastic#51535)
  Code coverage setup on CI (elastic#49003)
  [ML] DF Analytics Results: adds link to docs (elastic#54189)
  Update schemas boolean, byteSize, and duration to coerce strings (elastic#54177)
  [Metrics UI] Pass relevant shouldAllowEdit capabilities into SettingsPage (elastic#49781)
  [Canvas] Fixes bugs with autoplay and refresh (elastic#53149)
  [ML] DF Analytics Classification: ensure confusion matrix can be fetched (elastic#53629)
  Fix Vega react eslint errors (elastic#54259)
  Remove non existing codeowners (elastic#54274)
  use correct type (elastic#54244)
  [Dashboard] Removing 100% as dshDashboardViewport height (elastic#54263)
  add `examples/` to no-restricted-path config (elastic#54252)
  ...
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Kibana Management Feature label for Data Views, Advanced Setting, Saved Object management pages release_note:enhancement release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. v7.6.0 v8.0.0
Projects
kibana-app-arch
  
Done in previous release
Development

Successfully merging this pull request may close these issues.

None yet

8 participants