Skip to content

Commit

Permalink
Merge branch 'cases-rbac-poc' of github.com:elastic/kibana into add-s…
Browse files Browse the repository at this point in the history
…ecurity-only-tests
  • Loading branch information
jonathan-buttner committed May 10, 2021
2 parents 3f8fcd8 + b910889 commit 0610525
Show file tree
Hide file tree
Showing 124 changed files with 3,022 additions and 1,616 deletions.
66 changes: 38 additions & 28 deletions STYLEGUIDE.md → STYLEGUIDE.mdx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Kibana Style Guide
---
id: kibStyleGuide
slug: /kibana-dev-docs/styleguide
title: StyleGuide
summary: JavaScript/TypeScript styleguide.
date: 2021-05-06
tags: ['kibana', 'onboarding', 'dev', 'styleguide', 'typescript', 'javascript']
---

This guide applies to all development within the Kibana project and is
recommended for the development of all Kibana plugins.

- [General](#general)
- [HTML](#html)
- [API endpoints](#api-endpoints)
- [TypeScript/JavaScript](#typeScript/javaScript)
- [SASS files](#sass-files)
- [React](#react)

Besides the content in this style guide, the following style guides may also apply
to all development within the Kibana project. Please make sure to also read them:

Expand Down Expand Up @@ -52,9 +52,7 @@ This part contains style guide rules around general (framework agnostic) HTML us
Use camel case for the values of attributes such as `id` and `data-test-subj` selectors.

```html
<button id="veryImportantButton" data-test-subj="clickMeButton">
Click me
</button>
<button id="veryImportantButton" data-test-subj="clickMeButton">Click me</button>
```

The only exception is in cases where you're dynamically creating the value, and you need to use
Expand Down Expand Up @@ -378,6 +376,20 @@ import inFoo from 'foo/child';
import inSibling from '../foo/child';
```
#### Avoid export \* in top level index.ts files
The exports in `common/index.ts`, `public/index.ts` and `server/index.ts` dictate a plugin's public API. The public API should be carefully controlled, and using `export *` makes it very easy for a developer working on internal changes to export a new public API unintentionally.
```js
// good
export { foo } from 'foo';
export { child } from './child';

// bad
export * from 'foo/child';
export * from '../foo/child';
```
### Global definitions
Don't do this. Everything should be wrapped in a module that can be depended on
Expand Down Expand Up @@ -592,20 +604,20 @@ Do not use setters, they cause more problems than they can solve.
### Avoid circular dependencies
As part of a future effort to use correct and idempotent build tools we need our code to be
able to be represented as a directed acyclic graph. We must avoid having circular dependencies
both on code and type imports to achieve that. One of the most critical parts is the plugins
code. We've developed a tool to identify plugins with circular dependencies which
has allowed us to build a list of plugins who have circular dependencies
between each other.
When building plugins we should avoid importing from plugins
who are known to have circular dependencies at the moment as well as introducing
new circular dependencies. You can run the same tool we use on our CI locally by
typing `node scripts/find_plugins_with_circular_deps --debug`. It will error out in
case new circular dependencies has been added with your changes
able to be represented as a directed acyclic graph. We must avoid having circular dependencies
both on code and type imports to achieve that. One of the most critical parts is the plugins
code. We've developed a tool to identify plugins with circular dependencies which
has allowed us to build a list of plugins who have circular dependencies
between each other.
When building plugins we should avoid importing from plugins
who are known to have circular dependencies at the moment as well as introducing
new circular dependencies. You can run the same tool we use on our CI locally by
typing `node scripts/find_plugins_with_circular_deps --debug`. It will error out in
case new circular dependencies has been added with your changes
(which will also happen in the CI) as well as print out the current list of
the known circular dependencies which, as mentioned before, should not be imported
by your code until the circular dependencies on these have been solved.
the known circular dependencies which, as mentioned before, should not be imported
by your code until the circular dependencies on these have been solved.
## SASS files
Expand All @@ -626,10 +638,8 @@ import './component.scss';
// All other imports below the SASS import

export const Component = () => {
return (
<div className="plgComponent" />
);
}
return <div className="plgComponent" />;
};
```
```scss
Expand Down
Binary file added dev_docs/assets/kibana_custom_empty_state.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dev_docs/assets/kibana_default_empty_state.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions dev_docs/building_blocks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ Check out the Map Embeddable if you wish to embed a map in your application.

**Github labels**: `Team:Geo`

### KibanaPageTemplate

All Kibana pages should use KibanaPageTemplate to setup their pages. It's a thin wrapper around [EuiPageTemplate](https://elastic.github.io/eui/#/layout/page) that makes setting up common types of Kibana pages quicker and easier while also adhering to any Kibana-specific requirements.

Check out <DocLink id="kibDevDocsKBTTutorial" text="the KibanaPageTemplate tutorial" /> for more implementation guidance.

**Github labels**: `EUI`

## Searching

### Index Patterns
Expand Down
86 changes: 86 additions & 0 deletions dev_docs/tutorials/kibana_page_template.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
id: kibDevDocsKBLTutorial
slug: /kibana-dev-docs/tutorials/kibana-page-layout
title: KibanaPageLayout component
summary: Learn how to create pages in Kibana
date: 2021-03-20
tags: ['kibana', 'dev', 'ui', 'tutorials']
---

`KibanaPageLayout` is a thin wrapper around [EuiPageTemplate](https://elastic.github.io/eui/#/layout/page) that makes setting up common types of Kibana pages quicker and easier while also adhering to any Kibana-specific requirements and patterns.

Refer to EUI's documentation on [EuiPageTemplate](https://elastic.github.io/eui/#/layout/page) for constructing page layouts.

## `isEmptyState`

Use the `isEmptyState` prop for when there is no page content to show. For example, before the user has created something, when no search results are found, before data is populated, or when permissions aren't met.

The default empty state uses any `pageHeader` info provided to populate an [`EuiEmptyPrompt`](https://elastic.github.io/eui/#/display/empty-prompt) and uses the `centeredBody` template type.

```tsx
<KibanaPageLayout
isEmptyState={true}
pageHeader={{
iconType: 'dashboardApp',
pageTitle: 'Dashboards',
description: "You don't have any dashboards yet.",
rightSideItems: [
<EuiButton fill iconType="plusInCircleFilled">
Create new dashboard
</EuiButton>,
],
}}
/>
```

![Screenshot of demo empty state code. Shows the Kibana navigation bars and a centered empty state with the dashboard app icon, a level 1 heading "Dashboards", body text "You don't have any dashboards yet.", and a button that says "Create new dashboard".](../assets/kibana_default_empty_state.png)

<DocCallOut color="warning" title="Missing page header content can lead to an anemic empty state">
Because all properties of the page header are optional, the empty state has the potential to
render blank. Make sure your empty state doesn't leave the user confused.
</DocCallOut>

### Custom empty state

You can also provide a custom empty prompt to replace the pre-built one. You'll want to remove any `pageHeader` props and pass an [`EuiEmptyPrompt`](https://elastic.github.io/eui/#/display/empty-prompt) directly as the child of KibanaPageLayout.

```tsx
<KibanaPageLayout isEmptyState={true}>
<EuiEmptyPrompt
title={<h1>No data</h1>}
body="You have no data. Would you like some of ours?"
actions={[
<EuiButton fill iconType="plusInCircleFilled">
Get sample data
</EuiButton>,
]}
/>
</KibanaPageLayout>
```

![Screenshot of demo custom empty state code. Shows the Kibana navigation bars and a centered empty state with the a level 1 heading "No data", body text "You have no data. Would you like some of ours?", and a button that says "Get sample data".](../assets/kibana_custom_empty_state.png)

### Empty states with a page header

When passing both a `pageHeader` configuration and `isEmptyState`, the component will render the proper template (`centeredContent`). Be sure to reduce the heading level within your child empty prompt to `<h2>`.

```tsx
<KibanaPageLayout
isEmptyState={true}
pageHeader={{
pageTitle: 'Dashboards',
}}
>
<EuiEmptyPrompt
title={<h2>No data</h2>}
body="You have no data. Would you like some of ours?"
actions={[
<EuiButton fill iconType="plusInCircleFilled">
Get sample data
</EuiButton>,
]}
/>
</KibanaPageLayout>
```

![Screenshot of demo custom empty state code with a page header. Shows the Kibana navigation bars, a level 1 heading "Dashboards", and a centered empty state with the a level 2 heading "No data", body text "You have no data. Would you like some of ours?", and a button that says "Get sample data".](../assets/kibana_header_and_empty_state.png)
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@
"proxy-from-env": "1.0.0",
"proxyquire": "1.8.0",
"puid": "1.0.7",
"puppeteer": "npm:@elastic/[email protected]",
"puppeteer": "^8.0.0",
"query-string": "^6.13.2",
"raw-loader": "^3.1.0",
"rbush": "^3.0.1",
Expand Down Expand Up @@ -472,6 +472,7 @@
"@storybook/addon-knobs": "^6.1.20",
"@storybook/addon-storyshots": "^6.1.20",
"@storybook/addons": "^6.1.20",
"@storybook/api": "^6.1.20",
"@storybook/components": "^6.1.20",
"@storybook/core": "^6.1.20",
"@storybook/core-events": "^6.1.20",
Expand Down Expand Up @@ -585,7 +586,6 @@
"@types/pretty-ms": "^5.0.0",
"@types/prop-types": "^15.7.3",
"@types/proper-lockfile": "^3.0.1",
"@types/puppeteer": "^5.4.1",
"@types/rbush": "^3.0.0",
"@types/reach__router": "^1.2.6",
"@types/react": "^16.9.36",
Expand Down
3 changes: 3 additions & 0 deletions packages/kbn-storybook/lib/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import { addons } from '@storybook/addons';
import { create } from '@storybook/theming';
import { registerThemeSwitcherAddon } from './register_theme_switcher_addon';

// This configures the "Manager", or main outer view of Storybook. It is an
// addon that's loaded by the `managerEntries` part of the preset in ../preset.js.
Expand All @@ -22,3 +23,5 @@ addons.setConfig({
panelPosition: 'bottom',
isToolshown: true,
});

registerThemeSwitcherAddon();
36 changes: 36 additions & 0 deletions packages/kbn-storybook/lib/register_theme_switcher_addon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { addons, types } from '@storybook/addons';
import { ThemeSwitcher } from './theme_switcher';

export function registerThemeSwitcherAddon() {
addons.register('kibana/eui-theme-switcher', (api) => {
const channel = api.getChannel();

channel.on('globalsUpdated', ({ globals }) => {
const previewFrame = document.getElementById(
'storybook-preview-iframe'
) as HTMLIFrameElement | null;
const stylesheet = previewFrame?.contentDocument?.getElementById(
'eui-theme-css'
) as HTMLLinkElement | null;

if (stylesheet) {
stylesheet.href = `kbn-ui-shared-deps.${globals.euiTheme}.css`;
}
});

addons.add('kibana/eui-theme-switcher', {
title: 'EUI Theme Switcher',
type: types.TOOL,
match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)),
render: ThemeSwitcher,
});
});
}
2 changes: 1 addition & 1 deletion packages/kbn-storybook/lib/templates/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<script src="[email protected]"></script>
<script src="kbn-ui-shared-deps.js"></script>
<link href="kbn-ui-shared-deps.css" rel="stylesheet" />
<link href="kbn-ui-shared-deps.v7.light.css" rel="stylesheet" />
<link id="eui-theme-css" href="kbn-ui-shared-deps.v8.light.css" rel="stylesheet" />
<!-- -->

<% if (typeof headHtmlSnippet !== 'undefined') { %> <%= headHtmlSnippet %> <% } %> <%
Expand Down
62 changes: 62 additions & 0 deletions packages/kbn-storybook/lib/theme_switcher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React from 'react';
import { Icons, IconButton, TooltipLinkList, WithTooltip } from '@storybook/components';
import { useGlobals } from '@storybook/api';
import { Link } from '@storybook/components/dist/tooltip/TooltipLinkList';

const defaultTheme = 'v8.light';

export function ThemeSwitcher() {
const [globals, updateGlobals] = useGlobals();
const selectedTheme = globals.euiTheme;

if (!selectedTheme || selectedTheme === defaultTheme) {
updateGlobals({ euiTheme: defaultTheme });
}

function Menu({ onHide }: { onHide: () => void }) {
const links: Link[] = [
{
id: 'v8.light',
title: 'Amsterdam: Light',
},
{
id: 'v8.dark',
title: 'Amsterdam: Dark',
},
{ id: 'v7.light', title: 'Light' },
{ id: 'v7.dark', title: 'Dark' },
].map((link) => ({
...link,
onClick: (_event, item) => {
if (item.id !== selectedTheme) {
updateGlobals({ euiTheme: item.id });
}
onHide();
},
active: selectedTheme === link.id,
}));

return <TooltipLinkList links={links} />;
}

return (
<WithTooltip
placement="top"
trigger="click"
closeOnClick
tooltip={({ onHide }) => <Menu onHide={onHide} />}
>
<IconButton key="eui-theme" title="Change the EUI theme">
<Icons icon={selectedTheme?.includes('dark') ? 'heart' : 'hearthollow'} />
</IconButton>
</WithTooltip>
);
}
9 changes: 2 additions & 7 deletions packages/kbn-storybook/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@
"declarationMap": true,
"sourceMap": true,
"sourceRoot": "../../../../packages/kbn-storybook",
"types": [
"node"
]
"types": ["node"]
},
"include": [
"*.ts",
"lib/*.ts"
]
"include": ["*.ts", "lib/**/*.ts", "lib/**/*.tsx", "../../typings/index.d.ts"]
}
Loading

0 comments on commit 0610525

Please sign in to comment.