From 5eb53575f53707ca958ea3a16832f6e86988ce4e Mon Sep 17 00:00:00 2001 From: Liza K Date: Sun, 19 Jan 2020 18:21:04 +0200 Subject: [PATCH 01/23] Generate NP plugin --- packages/kbn-plugin-generator/index.js | 16 ++- .../kbn-plugin-generator/sao_template/sao.js | 46 ++++----- .../sao_template/template/.i18nrc.json | 9 -- .../template/.kibana-plugin-helpers.json | 3 - .../sao_template/template/README.md | 27 ------ .../sao_template/template/common/index.ts | 1 + .../sao_template/template/eslintrc.js | 24 ----- .../sao_template/template/gitignore | 6 -- .../sao_template/template/index.js | 89 ----------------- .../sao_template/template/kibana.json | 9 ++ .../template/package_template.json | 41 -------- .../template/public/__tests__/index.js | 7 -- .../sao_template/template/public/app.js | 45 --------- .../sao_template/template/public/app.scss | 0 .../template/public/components/app.tsx | 93 ++++++++++++++++++ .../template/public/components/main/index.js | 1 - .../template/public/components/main/main.js | 97 ------------------- .../sao_template/template/public/hack.js | 7 -- .../sao_template/template/public/index.ts | 13 +++ .../sao_template/template/public/plugin.ts | 34 +++++++ .../sao_template/template/public/types.ts | 3 + .../template/server/__tests__/index.js | 7 -- .../sao_template/template/server/index.ts | 9 ++ .../sao_template/template/server/plugin.ts | 21 ++++ .../template/server/routes/example.js | 11 --- .../template/translations/zh-CN.json | 84 ---------------- 26 files changed, 216 insertions(+), 487 deletions(-) delete mode 100644 packages/kbn-plugin-generator/sao_template/template/.i18nrc.json delete mode 100644 packages/kbn-plugin-generator/sao_template/template/.kibana-plugin-helpers.json create mode 100644 packages/kbn-plugin-generator/sao_template/template/common/index.ts delete mode 100755 packages/kbn-plugin-generator/sao_template/template/eslintrc.js delete mode 100755 packages/kbn-plugin-generator/sao_template/template/gitignore delete mode 100755 packages/kbn-plugin-generator/sao_template/template/index.js create mode 100644 packages/kbn-plugin-generator/sao_template/template/kibana.json delete mode 100644 packages/kbn-plugin-generator/sao_template/template/package_template.json delete mode 100755 packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js delete mode 100755 packages/kbn-plugin-generator/sao_template/template/public/app.js delete mode 100644 packages/kbn-plugin-generator/sao_template/template/public/app.scss create mode 100644 packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx delete mode 100644 packages/kbn-plugin-generator/sao_template/template/public/components/main/index.js delete mode 100644 packages/kbn-plugin-generator/sao_template/template/public/components/main/main.js delete mode 100755 packages/kbn-plugin-generator/sao_template/template/public/hack.js create mode 100644 packages/kbn-plugin-generator/sao_template/template/public/index.ts create mode 100644 packages/kbn-plugin-generator/sao_template/template/public/plugin.ts create mode 100644 packages/kbn-plugin-generator/sao_template/template/public/types.ts delete mode 100755 packages/kbn-plugin-generator/sao_template/template/server/__tests__/index.js create mode 100644 packages/kbn-plugin-generator/sao_template/template/server/index.ts create mode 100644 packages/kbn-plugin-generator/sao_template/template/server/plugin.ts delete mode 100755 packages/kbn-plugin-generator/sao_template/template/server/routes/example.js delete mode 100644 packages/kbn-plugin-generator/sao_template/template/translations/zh-CN.json diff --git a/packages/kbn-plugin-generator/index.js b/packages/kbn-plugin-generator/index.js index 90274288357b8..15adce7f01c8e 100644 --- a/packages/kbn-plugin-generator/index.js +++ b/packages/kbn-plugin-generator/index.js @@ -29,6 +29,7 @@ exports.run = function run(argv) { const options = getopts(argv, { alias: { h: 'help', + i: 'internal', }, }); @@ -40,17 +41,22 @@ exports.run = function run(argv) { if (options.help) { console.log( dedent(chalk` - {dim usage:} node scripts/generate-plugin {bold [name]} - - generate a fresh Kibana plugin in the plugins/ directory + # {dim Usage:} + node scripts/generate-plugin {bold [name]} + Generate a fresh Kibana plugin in the plugins/ directory + + # {dim Core Kibana plugins:} + node scripts/generate-plugin {bold [name]} -i + To generate a core Kibana plugin inside the src/plugins/ directory, add the -i flag. `) + '\n' ); process.exit(1); } const name = options._[0]; + const isKibanaPlugin = options.internal; const template = resolve(__dirname, './sao_template'); - const kibanaPlugins = resolve(__dirname, '../../plugins'); + const kibanaPlugins = resolve(__dirname, isKibanaPlugin ? '../../src/plugins' : '../../plugins'); const targetPath = resolve(kibanaPlugins, snakeCase(name)); sao({ @@ -58,6 +64,8 @@ exports.run = function run(argv) { targetPath: targetPath, configOptions: { name, + isKibanaPlugin, + targetPath, }, }).catch(error => { console.error(chalk`{red fatal error}!`); diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index f7401cba84358..79e385ffe4c0e 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -17,21 +17,18 @@ * under the License. */ -const { resolve, relative, dirname } = require('path'); +const { relative } = require('path'); const startCase = require('lodash.startcase'); const camelCase = require('lodash.camelcase'); const snakeCase = require('lodash.snakecase'); -const execa = require('execa'); const chalk = require('chalk'); const pkg = require('../package.json'); const kibanaPkgPath = require.resolve('../../../package.json'); const kibanaPkg = require(kibanaPkgPath); // eslint-disable-line import/no-dynamic-require -const KBN_DIR = dirname(kibanaPkgPath); - -module.exports = function({ name }) { +module.exports = function({ name, targetPath, isKibanaPlugin }) { return { prompts: { description: { @@ -52,11 +49,6 @@ module.exports = function({ name }) { message: 'Should translation files be generated?', default: true, }, - generateHack: { - type: 'confirm', - message: 'Should a hack component be generated?', - default: true, - }, generateApi: { type: 'confirm', message: 'Should a server API be generated?', @@ -73,7 +65,6 @@ module.exports = function({ name }) { 'public/**/*': 'generateApp', 'translations/**/*': 'generateTranslations', '.i18nrc.json': 'generateTranslations', - 'public/hack.js': 'generateHack', 'server/**/*': 'generateApi', 'public/app.scss': 'generateScss', '.kibana-plugin-helpers.json': 'generateScss', @@ -91,28 +82,33 @@ module.exports = function({ name }) { camelCase, snakeCase, name, + kbnVersion: answers.kbnVersion, + camelCaseName: name.charAt(0).toUpperCase() + camelCase(name).slice(1), + hasUi: !!answers.generateApp, + hasServer: !!answers.generateApi, + relRoot: isKibanaPlugin ? '../../../..' : '../../..', }, answers ), enforceNewFolder: true, installDependencies: false, - gitInit: true, + gitInit: !isKibanaPlugin, async post({ log }) { - await execa('yarn', ['kbn', 'bootstrap'], { - cwd: KBN_DIR, - stdio: 'inherit', - }); + // await execa('yarn', ['kbn', 'bootstrap'], { + // cwd: KBN_DIR, + // stdio: 'inherit', + // }); - const dir = relative(process.cwd(), resolve(KBN_DIR, 'plugins', snakeCase(name))); + const dir = relative(process.cwd(), targetPath); - try { - await execa('yarn', ['lint', '--fix'], { - cwd: dir, - all: true, - }); - } catch (error) { - throw new Error(`Failure when running prettier on the generated output: ${error.all}`); - } + // try { + // await execa('yarn', ['lint', '--fix'], { + // cwd: dir, + // all: true, + // }); + // } catch (error) { + // throw new Error(`Failure when running prettier on the generated output: ${error.all}`); + // } log.success(chalk`🎉 diff --git a/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json b/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json deleted file mode 100644 index 1a8aea8853876..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "paths": { - "<%= camelCase(name) %>": "./" - }, - "translations": [ - "translations/zh-CN.json" - ] -} - diff --git a/packages/kbn-plugin-generator/sao_template/template/.kibana-plugin-helpers.json b/packages/kbn-plugin-generator/sao_template/template/.kibana-plugin-helpers.json deleted file mode 100644 index 383368c7f8ce1..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/.kibana-plugin-helpers.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "styleSheetToCompile": "public/app.scss" -} diff --git a/packages/kbn-plugin-generator/sao_template/template/README.md b/packages/kbn-plugin-generator/sao_template/template/README.md index 59c3adf2713c8..acd1ede5a573e 100755 --- a/packages/kbn-plugin-generator/sao_template/template/README.md +++ b/packages/kbn-plugin-generator/sao_template/template/README.md @@ -10,30 +10,3 @@ See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment. Once you have completed that, use the following yarn scripts. - - `yarn kbn bootstrap` - - Install dependencies and crosslink Kibana and all projects/plugins. - - > ***IMPORTANT:*** Use this script instead of `yarn` to install dependencies when switching branches, and re-run it whenever your dependencies change. - - - `yarn start` - - Start kibana and have it include this plugin. You can pass any arguments that you would normally send to `bin/kibana` - - ``` - yarn start --elasticsearch.hosts http://localhost:9220 - ``` - - - `yarn build` - - Build a distributable archive of your plugin. - - - `yarn test:browser` - - Run the browser tests in a real web browser. - - - `yarn test:mocha` - - Run the server tests using mocha. - -For more information about any of these commands run `yarn ${task} --help`. For a full list of tasks checkout the `package.json` file, or run `yarn run`. diff --git a/packages/kbn-plugin-generator/sao_template/template/common/index.ts b/packages/kbn-plugin-generator/sao_template/template/common/index.ts new file mode 100644 index 0000000000000..95b6908a2a3e3 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/common/index.ts @@ -0,0 +1 @@ +export const PLUGIN_NAME = '<%= name %>'; \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/eslintrc.js b/packages/kbn-plugin-generator/sao_template/template/eslintrc.js deleted file mode 100755 index e1dfadc212b7e..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/eslintrc.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - root: true, - extends: ['@elastic/eslint-config-kibana', 'plugin:@elastic/eui/recommended'], - settings: { - 'import/resolver': { - '@kbn/eslint-import-resolver-kibana': { - rootPackageName: '<%= snakeCase(name) %>', - }, - }, - }, - overrides: [ - { - files: ['**/public/**/*'], - settings: { - 'import/resolver': { - '@kbn/eslint-import-resolver-kibana': { - forceNode: false, - rootPackageName: '<%= snakeCase(name) %>', - }, - }, - }, - }, - ] -}; diff --git a/packages/kbn-plugin-generator/sao_template/template/gitignore b/packages/kbn-plugin-generator/sao_template/template/gitignore deleted file mode 100755 index db28fed19376d..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/gitignore +++ /dev/null @@ -1,6 +0,0 @@ -npm-debug.log* -node_modules -/build/ -<%_ if (generateScss) { -%> -/public/app.css -<%_ } -%> diff --git a/packages/kbn-plugin-generator/sao_template/template/index.js b/packages/kbn-plugin-generator/sao_template/template/index.js deleted file mode 100755 index 4bc3347ae6019..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/index.js +++ /dev/null @@ -1,89 +0,0 @@ -<% if (generateScss) { -%> -import { resolve } from 'path'; -import { existsSync } from 'fs'; - -<% } -%> - -<% if (generateApp) { -%> -import { i18n } from '@kbn/i18n'; -<% } -%> - -<% if (generateApi) { -%> -import exampleRoute from './server/routes/example'; - -<% } -%> -export default function (kibana) { - return new kibana.Plugin({ - require: ['elasticsearch'], - name: '<%= snakeCase(name) %>', - uiExports: { - <%_ if (generateApp) { -%> - app: { - title: '<%= startCase(name) %>', - description: '<%= description %>', - main: 'plugins/<%= snakeCase(name) %>/app', - }, - <%_ } -%> - <%_ if (generateHack) { -%> - hacks: [ - 'plugins/<%= snakeCase(name) %>/hack' - ], - <%_ } -%> - <%_ if (generateScss) { -%> - styleSheetPaths: [resolve(__dirname, 'public/app.scss'), resolve(__dirname, 'public/app.css')].find(p => existsSync(p)), - <%_ } -%> - }, - - config(Joi) { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - <%_ if (generateApi || generateApp) { -%> - - // eslint-disable-next-line no-unused-vars - init(server, options) { - <%_ if (generateApp) { -%> - const xpackMainPlugin = server.plugins.xpack_main; - if (xpackMainPlugin) { - const featureId = '<%= snakeCase(name) %>'; - - xpackMainPlugin.registerFeature({ - id: featureId, - name: i18n.translate('<%= camelCase(name) %>.featureRegistry.featureName', { - defaultMessage: '<%= name %>', - }), - navLinkId: featureId, - icon: 'questionInCircle', - app: [featureId, 'kibana'], - catalogue: [], - privileges: { - all: { - api: [], - savedObject: { - all: [], - read: [], - }, - ui: ['show'], - }, - read: { - api: [], - savedObject: { - all: [], - read: [], - }, - ui: ['show'], - }, - }, - }); - } - <%_ } -%> - - <%_ if (generateApi) { -%> - // Add server routes and initialize the plugin here - exampleRoute(server); - <%_ } -%> - } - <%_ } -%> - }); -} diff --git a/packages/kbn-plugin-generator/sao_template/template/kibana.json b/packages/kbn-plugin-generator/sao_template/template/kibana.json new file mode 100644 index 0000000000000..ccdf8a263e847 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/kibana.json @@ -0,0 +1,9 @@ +{ + "id": "<%= camelCase(name) %>", + "version": "<%= kbnVersion %>", + "server": <%= hasServer %>, + "ui": <%= hasUi %>, + "requiredPlugins": [], + "optionalPlugins": [] + } + \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/package_template.json b/packages/kbn-plugin-generator/sao_template/template/package_template.json deleted file mode 100644 index 4b6629fa90268..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/package_template.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "<%= snakeCase(name) %>", - "version": "0.0.0", - "description": "<%= description %>", - "main": "index.js", - "kibana": { - "version": "<%= (kbnVersion === 'master') ? 'kibana' : kbnVersion %>", - "templateVersion": "<%= templateVersion %>" - }, - "scripts": { - "preinstall": "node ../../preinstall_check", - "kbn": "node ../../scripts/kbn", - "es": "node ../../scripts/es", - "lint": "eslint .", - "start": "plugin-helpers start", - "test:server": "plugin-helpers test:server", - "test:browser": "plugin-helpers test:browser", - "build": "plugin-helpers build" - }, - <%_ if (generateTranslations) { _%> - "dependencies": { - "@kbn/i18n": "link:../../packages/kbn-i18n" - }, - <%_ } _%> - "devDependencies": { - "@elastic/eslint-config-kibana": "link:../../packages/eslint-config-kibana", - "@elastic/eslint-import-resolver-kibana": "link:../../packages/kbn-eslint-import-resolver-kibana", - "@kbn/expect": "link:../../packages/kbn-expect", - "@kbn/plugin-helpers": "link:../../packages/kbn-plugin-helpers", - "babel-eslint": "^10.0.1", - "eslint": "^5.16.0", - "eslint-plugin-babel": "^5.3.0", - "eslint-plugin-import": "^2.16.0", - "eslint-plugin-jest": "^22.4.1", - "eslint-plugin-jsx-a11y": "^6.2.1", - "eslint-plugin-mocha": "^5.3.0", - "eslint-plugin-no-unsanitized": "^3.0.2", - "eslint-plugin-prefer-object-spread": "^1.2.1", - "eslint-plugin-react": "^7.12.4" - } -} diff --git a/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js b/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js deleted file mode 100755 index 9320bd7b028a8..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import expect from '@kbn/expect'; - -describe('suite', () => { - it('is a test', () => { - expect(true).to.equal(true); - }); -}); diff --git a/packages/kbn-plugin-generator/sao_template/template/public/app.js b/packages/kbn-plugin-generator/sao_template/template/public/app.js deleted file mode 100755 index 37a7c37e916a0..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/public/app.js +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react'; -import { uiModules } from 'ui/modules'; -import chrome from 'ui/chrome'; -import { render, unmountComponentAtNode } from 'react-dom'; -<%_ if (generateTranslations) { _%> -import { I18nProvider } from '@kbn/i18n/react'; -<%_ } _%> - -import { Main } from './components/main'; - -const app = uiModules.get('apps/<%= camelCase(name) %>'); - -app.config($locationProvider => { - $locationProvider.html5Mode({ - enabled: false, - requireBase: false, - rewriteLinks: false, - }); -}); -app.config(stateManagementConfigProvider => - stateManagementConfigProvider.disable() -); - -function RootController($scope, $element, $http) { - const domNode = $element[0]; - - // render react to DOM - <%_ if (generateTranslations) { _%> - render( - -
- , - domNode - ); - <%_ } else { _%> - render(
, domNode); - <%_ } _%> - - // unmount react on controller destroy - $scope.$on('$destroy', () => { - unmountComponentAtNode(domNode); - }); -} - -chrome.setRootController('<%= camelCase(name) %>', RootController); diff --git a/packages/kbn-plugin-generator/sao_template/template/public/app.scss b/packages/kbn-plugin-generator/sao_template/template/public/app.scss deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx new file mode 100644 index 0000000000000..b88c80c4bb557 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -0,0 +1,93 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { BrowserRouter as Router, Route, withRouter, RouteComponentProps } from 'react-router-dom'; + +import { + EuiPage, + EuiPageBody, + EuiPageContent, + EuiPageContentBody, + EuiPageContentHeader, + EuiPageHeader, + EuiTitle, + EuiText, +} from '@elastic/eui'; + +import { AppMountContext, AppMountParameters } from '<%= relRoot %>/../src/core/public'; + +const FooApp = ({ basename, context }: { basename: string; context: AppMountContext }) => ( + + + + + +

+ +

+
+
+ + + +

+ +

+
+
+ + +

+ +

+

+ +

+
+
+
+
+
+
+); + +export const renderApp = ( + context: AppMountContext, + { appBasePath, element }: AppMountParameters +) => { + ReactDOM.render(, element); + + return () => ReactDOM.unmountComponentAtNode(element); +}; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/main/index.js b/packages/kbn-plugin-generator/sao_template/template/public/components/main/index.js deleted file mode 100644 index 68710baa1bee8..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/main/index.js +++ /dev/null @@ -1 +0,0 @@ -export { Main } from './main'; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/main/main.js b/packages/kbn-plugin-generator/sao_template/template/public/components/main/main.js deleted file mode 100644 index 59fd667c709aa..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/main/main.js +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react'; -import { - EuiPage, - EuiPageHeader, - EuiTitle, - EuiPageBody, - EuiPageContent, - EuiPageContentHeader, - EuiPageContentBody, - EuiText -} from '@elastic/eui'; -<%_ if (generateTranslations) { _%> -import { FormattedMessage } from '@kbn/i18n/react'; -<%_ } _%> - -export class Main extends React.Component { - constructor(props) { - super(props); - this.state = {}; - } - - componentDidMount() { - /* - FOR EXAMPLE PURPOSES ONLY. There are much better ways to - manage state and update your UI than this. - */ - const { httpClient } = this.props; - httpClient.get('../api/<%= name %>/example').then((resp) => { - this.setState({ time: resp.data.time }); - }); - } - render() { - const { title } = this.props; - return ( - - - - -

- <%_ if (generateTranslations) { _%> - - <%_ } else { _%> - {title} Hello World! - <%_ } _%> -

-
-
- - - -

- <%_ if (generateTranslations) { _%> - - <%_ } else { _%> - Congratulations - <%_ } _%> -

-
-
- - -

- <%_ if (generateTranslations) { _%> - - <%_ } else { _%> - You have successfully created your first Kibana Plugin! - <%_ } _%> -

-

- <%_ if (generateTranslations) { _%> - - <%_ } else { _%> - The server time (via API call) is {this.state.time || 'NO API CALL YET'} - <%_ } _%> -

-
-
-
-
-
- ); - } -} diff --git a/packages/kbn-plugin-generator/sao_template/template/public/hack.js b/packages/kbn-plugin-generator/sao_template/template/public/hack.js deleted file mode 100755 index 775526c8e44a3..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/public/hack.js +++ /dev/null @@ -1,7 +0,0 @@ -import $ from 'jquery'; - -$(document.body).on('keypress', function (event) { - if (event.which === 58) { - alert('boo!'); - } -}); diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts new file mode 100644 index 0000000000000..8b8e3db0e57b9 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/public/index.ts @@ -0,0 +1,13 @@ + + +import { PluginInitializerContext } from '<%= relRoot %>/src/core/public'; +export function plugin(initializerContext: PluginInitializerContext) { + return new <%= camelCaseName %>PublicPlugin(initializerContext); +} + +export * from '../common'; +export * from './types'; + +// Export plugin after all other imports +import { <%= camelCaseName %>PublicPlugin } from './plugin'; +export { <%= camelCaseName %>PublicPlugin as Plugin }; \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts new file mode 100644 index 0000000000000..8c9f4e84a1380 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts @@ -0,0 +1,34 @@ +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, AppMountContext } from '<%= relRoot %>/src/core/public'; +import { + <%= camelCaseName %>PublicPluginSetup, + <%= camelCaseName %>PublicPluginStart, +} from './types'; +import { PLUGIN_NAME } from '../common'; + +export class <%= camelCaseName %>PublicPlugin implements Plugin<<%= camelCaseName %>PublicPluginSetup, <%= camelCaseName %>PublicPluginStart> { + constructor(initializerContext: PluginInitializerContext) { + } + + public setup(core: CoreSetup): <%= camelCaseName %>PublicPluginSetup { + core.application.register({ + id: '<%= camelCase(name) %>', + title: PLUGIN_NAME, + async mount(context: AppMountContext, params: any) { + const { renderApp } = await import('./components/app'); + return renderApp(context, params); + }, + }); + + return { + getGreeting() { + return 'Hello from Plugin A!'; + }, + }; + } + + public start(core: CoreStart): <%= camelCaseName %>PublicPluginStart { + return {} + } + + public stop() {} +} \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/public/types.ts b/packages/kbn-plugin-generator/sao_template/template/public/types.ts new file mode 100644 index 0000000000000..b5ff60135ded0 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/public/types.ts @@ -0,0 +1,3 @@ + +export interface <%= camelCaseName %>PublicPluginSetup {} +export interface <%= camelCaseName %>PublicPluginStart {} \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/server/__tests__/index.js b/packages/kbn-plugin-generator/sao_template/template/server/__tests__/index.js deleted file mode 100755 index 9320bd7b028a8..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/server/__tests__/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import expect from '@kbn/expect'; - -describe('suite', () => { - it('is a test', () => { - expect(true).to.equal(true); - }); -}); diff --git a/packages/kbn-plugin-generator/sao_template/template/server/index.ts b/packages/kbn-plugin-generator/sao_template/template/server/index.ts new file mode 100644 index 0000000000000..b76a7b9a4116e --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/server/index.ts @@ -0,0 +1,9 @@ +import { PluginInitializerContext } from '<%= relRoot %>/src/core/server'; +import { <%= camelCaseName %>ServerPlugin } from './plugin'; + +export function plugin(initializerContext: PluginInitializerContext) { + return new <%= camelCaseName %>ServerPlugin(initializerContext); +} + +export { <%= camelCaseName %>ServerPlugin as Plugin }; +export * from '../common'; \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts new file mode 100644 index 0000000000000..2c0eae6a99843 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts @@ -0,0 +1,21 @@ + +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/server'; + +export interface <%= camelCaseName %>PluginSetup {}; +export interface <%= camelCaseName %>PluginStart {}; + +export class <%= camelCaseName %>ServerPlugin implements Plugin<<%= camelCaseName %>PluginSetup, <%= camelCaseName %>PluginStart> { + constructor(initializerContext: PluginInitializerContext) {} + + public setup(core: CoreSetup) { + return {}; + } + + public start(core: CoreStart) { + return {}; + } + + public stop() {} +} + +export { <%= camelCaseName %>ServerPlugin as Plugin }; \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/server/routes/example.js b/packages/kbn-plugin-generator/sao_template/template/server/routes/example.js deleted file mode 100755 index 5a612645f48fc..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/server/routes/example.js +++ /dev/null @@ -1,11 +0,0 @@ -export default function (server) { - - server.route({ - path: '/api/<%= name %>/example', - method: 'GET', - handler() { - return { time: (new Date()).toISOString() }; - } - }); - -} diff --git a/packages/kbn-plugin-generator/sao_template/template/translations/zh-CN.json b/packages/kbn-plugin-generator/sao_template/template/translations/zh-CN.json deleted file mode 100644 index 3447511c6739a..0000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/translations/zh-CN.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "formats": { - "number": { - "currency": { - "style": "currency" - }, - "percent": { - "style": "percent" - } - }, - "date": { - "short": { - "month": "numeric", - "day": "numeric", - "year": "2-digit" - }, - "medium": { - "month": "short", - "day": "numeric", - "year": "numeric" - }, - "long": { - "month": "long", - "day": "numeric", - "year": "numeric" - }, - "full": { - "weekday": "long", - "month": "long", - "day": "numeric", - "year": "numeric" - } - }, - "time": { - "short": { - "hour": "numeric", - "minute": "numeric" - }, - "medium": { - "hour": "numeric", - "minute": "numeric", - "second": "numeric" - }, - "long": { - "hour": "numeric", - "minute": "numeric", - "second": "numeric", - "timeZoneName": "short" - }, - "full": { - "hour": "numeric", - "minute": "numeric", - "second": "numeric", - "timeZoneName": "short" - } - }, - "relative": { - "years": { - "units": "year" - }, - "months": { - "units": "month" - }, - "days": { - "units": "day" - }, - "hours": { - "units": "hour" - }, - "minutes": { - "units": "minute" - }, - "seconds": { - "units": "second" - } - } - }, - "messages": { - "<%= camelCase(name) %>.congratulationsText": "您已经成功创建第一个 Kibana 插件。", - "<%= camelCase(name) %>.congratulationsTitle": "恭喜!", - "<%= camelCase(name) %>.helloWorldText": "{title} 您好,世界!", - "<%= camelCase(name) %>.serverTimeText": "服务器时间(通过 API 调用)为 {time}" - } -} From f44b2c39e7915443999f9fe8c99813927d85ad41 Mon Sep 17 00:00:00 2001 From: Liza K Date: Mon, 20 Jan 2020 10:58:45 +0200 Subject: [PATCH 02/23] Added tsconfig --- packages/kbn-plugin-generator/tsconfig.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/kbn-plugin-generator/tsconfig.json diff --git a/packages/kbn-plugin-generator/tsconfig.json b/packages/kbn-plugin-generator/tsconfig.json new file mode 100644 index 0000000000000..637200f829740 --- /dev/null +++ b/packages/kbn-plugin-generator/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.json", + "include": ["sao_template/**/*"], + "exclude": ["sao_template/template/*"] +} From 65e621d63162d2b7747a48fdb45b0a1f40be84ae Mon Sep 17 00:00:00 2001 From: Liza K Date: Mon, 20 Jan 2020 12:18:55 +0200 Subject: [PATCH 03/23] tsconfig --- packages/kbn-plugin-generator/index.js.d.ts | 24 +++++++++++++++++++++ packages/kbn-plugin-generator/tsconfig.json | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 packages/kbn-plugin-generator/index.js.d.ts diff --git a/packages/kbn-plugin-generator/index.js.d.ts b/packages/kbn-plugin-generator/index.js.d.ts new file mode 100644 index 0000000000000..c3e6595e1c993 --- /dev/null +++ b/packages/kbn-plugin-generator/index.js.d.ts @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +interface PluginGenerator { + /** + * Run plugin generator. + */ + run: any; +} diff --git a/packages/kbn-plugin-generator/tsconfig.json b/packages/kbn-plugin-generator/tsconfig.json index 637200f829740..fe0f7112f1fa9 100644 --- a/packages/kbn-plugin-generator/tsconfig.json +++ b/packages/kbn-plugin-generator/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "../../tsconfig.json", - "include": ["sao_template/**/*"], + "include": ["**/*", "index.js.d.ts"], "exclude": ["sao_template/template/*"] } From b97282771f60abf31367a2640417b5d0203cc1f3 Mon Sep 17 00:00:00 2001 From: Liza K Date: Mon, 20 Jan 2020 14:35:32 +0200 Subject: [PATCH 04/23] Adjust sao test --- .../sao_template/sao.test.js | 87 +++++-------------- .../sao_template/template/common/index.ts | 1 + 2 files changed, 21 insertions(+), 67 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/sao.test.js b/packages/kbn-plugin-generator/sao_template/sao.test.js index 80149c008dad8..e353bb2be6c0b 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.test.js +++ b/packages/kbn-plugin-generator/sao_template/sao.test.js @@ -38,10 +38,9 @@ function getConfig(file) { } describe('plugin generator sao integration', () => { - test('skips files when answering no', async () => { + test.skip('skips files when answering no', async () => { const res = await sao.mockPrompt(template, { generateApp: false, - generateHack: false, generateApi: false, }); @@ -61,49 +60,20 @@ describe('plugin generator sao integration', () => { it('includes app when answering yes', async () => { const res = await sao.mockPrompt(template, { generateApp: true, - generateHack: false, generateApi: false, }); // check output files - expect(res.fileList).toContain('public/app.js'); - expect(res.fileList).toContain('public/__tests__/index.js'); - expect(res.fileList).not.toContain('public/hack.js'); - expect(res.fileList).not.toContain('server/routes/example.js'); - expect(res.fileList).not.toContain('server/__tests__/index.js'); - - const uiExports = getConfig(res.files['index.js']); - expect(uiExports).toContain('app:'); - expect(uiExports).toContain('init(server, options)'); - expect(uiExports).toContain('registerFeature('); - expect(uiExports).not.toContain('hacks:'); + expect(res.fileList).toContain('common/index.ts'); + expect(res.fileList).toContain('public/index.ts'); + expect(res.fileList).toContain('public/plugin.ts'); + expect(res.fileList).toContain('public/types.ts'); + expect(res.fileList).toContain('public/components/app.tsx'); }); - it('includes hack when answering yes', async () => { + it.skip('includes server api when answering yes', async () => { const res = await sao.mockPrompt(template, { generateApp: true, - generateHack: true, - generateApi: false, - }); - - // check output files - expect(res.fileList).toContain('public/app.js'); - expect(res.fileList).toContain('public/__tests__/index.js'); - expect(res.fileList).toContain('public/hack.js'); - expect(res.fileList).not.toContain('server/routes/example.js'); - expect(res.fileList).not.toContain('server/__tests__/index.js'); - - const uiExports = getConfig(res.files['index.js']); - expect(uiExports).toContain('app:'); - expect(uiExports).toContain('hacks:'); - expect(uiExports).toContain('init(server, options)'); - expect(uiExports).toContain('registerFeature('); - }); - - it('includes server api when answering yes', async () => { - const res = await sao.mockPrompt(template, { - generateApp: true, - generateHack: true, generateApi: true, }); @@ -121,32 +91,16 @@ describe('plugin generator sao integration', () => { expect(uiExports).toContain('registerFeature('); }); - it('plugin config has correct name and main path', async () => { + it('plugin package has correct title', async () => { const res = await sao.mockPrompt(template, { generateApp: true, - generateHack: true, generateApi: true, }); - const indexContents = getFileContents(res.files['index.js']); - const nameLine = indexContents.match('name: (.*)')[1]; - const mainLine = indexContents.match('main: (.*)')[1]; - - expect(nameLine).toContain('some_fancy_plugin'); - expect(mainLine).toContain('plugins/some_fancy_plugin/app'); - }); - - it('plugin package has correct name', async () => { - const res = await sao.mockPrompt(template, { - generateApp: true, - generateHack: true, - generateApi: true, - }); - - const packageContents = getFileContents(res.files['package.json']); - const pkg = JSON.parse(packageContents); + const contents = getFileContents(res.files['common/index.ts']); + const controllerLine = contents.match("PLUGIN_NAME = '(.*)'")[1]; - expect(pkg.name).toBe('some_fancy_plugin'); + expect(controllerLine).toContain('Some fancy plugin'); }); it('package has version "kibana" with master', async () => { @@ -154,10 +108,10 @@ describe('plugin generator sao integration', () => { kbnVersion: 'master', }); - const packageContents = getFileContents(res.files['package.json']); + const packageContents = getFileContents(res.files['kibana.json']); const pkg = JSON.parse(packageContents); - expect(pkg.kibana.version).toBe('kibana'); + expect(pkg.version).toBe('master'); }); it('package has correct version', async () => { @@ -165,18 +119,18 @@ describe('plugin generator sao integration', () => { kbnVersion: 'v6.0.0', }); - const packageContents = getFileContents(res.files['package.json']); + const packageContents = getFileContents(res.files['kibana.json']); const pkg = JSON.parse(packageContents); - expect(pkg.kibana.version).toBe('v6.0.0'); + expect(pkg.version).toBe('v6.0.0'); }); - it('package has correct templateVersion', async () => { + it.skip('package has correct templateVersion', async () => { const res = await sao.mockPrompt(template, { kbnVersion: 'master', }); - const packageContents = getFileContents(res.files['package.json']); + const packageContents = getFileContents(res.files['kibana.json']); const pkg = JSON.parse(packageContents); expect(pkg.kibana.templateVersion).toBe(templatePkg.version); @@ -185,17 +139,16 @@ describe('plugin generator sao integration', () => { it('sample app has correct values', async () => { const res = await sao.mockPrompt(template, { generateApp: true, - generateHack: true, generateApi: true, }); - const contents = getFileContents(res.files['public/app.js']); - const controllerLine = contents.match('setRootController(.*)')[1]; + const contents = getFileContents(res.files['common/index.ts']); + const controllerLine = contents.match("PLUGIN_ID = '(.*)'")[1]; expect(controllerLine).toContain('someFancyPlugin'); }); - it('includes dotfiles', async () => { + it.skip('includes dotfiles', async () => { const res = await sao.mockPrompt(template); expect(res.files['.gitignore']).toBeTruthy(); expect(res.files['.eslintrc.js']).toBeTruthy(); diff --git a/packages/kbn-plugin-generator/sao_template/template/common/index.ts b/packages/kbn-plugin-generator/sao_template/template/common/index.ts index 95b6908a2a3e3..fd5676e472c2e 100644 --- a/packages/kbn-plugin-generator/sao_template/template/common/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/common/index.ts @@ -1 +1,2 @@ +export const PLUGIN_ID = '<%= camelCase(name) %>'; export const PLUGIN_NAME = '<%= name %>'; \ No newline at end of file From 3fa50aa814235141e6da42bd08a60c986521d5e4 Mon Sep 17 00:00:00 2001 From: Liza K Date: Mon, 20 Jan 2020 18:14:57 +0200 Subject: [PATCH 05/23] Add server side to plugin gen --- packages/kbn-plugin-generator/index.js.d.ts | 2 +- .../kbn-plugin-generator/sao_template/sao.js | 2 +- .../sao_template/template/common/index.ts | 2 +- .../sao_template/template/kibana.json | 15 +- .../template/public/components/app.tsx | 134 +++++++++++------- .../sao_template/template/public/index.ts | 11 +- .../sao_template/template/public/plugin.ts | 35 +++-- .../sao_template/template/public/types.ts | 6 +- .../sao_template/template/server/index.ts | 8 +- .../sao_template/template/server/plugin.ts | 25 +++- .../sao_template/template/server/types.ts | 2 + 11 files changed, 150 insertions(+), 92 deletions(-) create mode 100644 packages/kbn-plugin-generator/sao_template/template/server/types.ts diff --git a/packages/kbn-plugin-generator/index.js.d.ts b/packages/kbn-plugin-generator/index.js.d.ts index c3e6595e1c993..46f7c43fd5790 100644 --- a/packages/kbn-plugin-generator/index.js.d.ts +++ b/packages/kbn-plugin-generator/index.js.d.ts @@ -20,5 +20,5 @@ interface PluginGenerator { /** * Run plugin generator. */ - run: any; + run: (...args: any[]) => any; } diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index 79e385ffe4c0e..bde118c69149e 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -83,7 +83,7 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { snakeCase, name, kbnVersion: answers.kbnVersion, - camelCaseName: name.charAt(0).toUpperCase() + camelCase(name).slice(1), + upperCamelCaseName: name.charAt(0).toUpperCase() + camelCase(name).slice(1), hasUi: !!answers.generateApp, hasServer: !!answers.generateApi, relRoot: isKibanaPlugin ? '../../../..' : '../../..', diff --git a/packages/kbn-plugin-generator/sao_template/template/common/index.ts b/packages/kbn-plugin-generator/sao_template/template/common/index.ts index fd5676e472c2e..90ffcb70045aa 100644 --- a/packages/kbn-plugin-generator/sao_template/template/common/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/common/index.ts @@ -1,2 +1,2 @@ export const PLUGIN_ID = '<%= camelCase(name) %>'; -export const PLUGIN_NAME = '<%= name %>'; \ No newline at end of file +export const PLUGIN_NAME = '<%= name %>'; diff --git a/packages/kbn-plugin-generator/sao_template/template/kibana.json b/packages/kbn-plugin-generator/sao_template/template/kibana.json index ccdf8a263e847..1d8473bdcf34c 100644 --- a/packages/kbn-plugin-generator/sao_template/template/kibana.json +++ b/packages/kbn-plugin-generator/sao_template/template/kibana.json @@ -1,9 +1,8 @@ { - "id": "<%= camelCase(name) %>", - "version": "<%= kbnVersion %>", - "server": <%= hasServer %>, - "ui": <%= hasUi %>, - "requiredPlugins": [], - "optionalPlugins": [] - } - \ No newline at end of file + "id": "<%= camelCase(name) %>", + "version": "<%= kbnVersion %>", + "server": <%= hasServer %>, + "ui": <%= hasUi %>, + "requiredPlugins": [], + "optionalPlugins": [] +} diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index b88c80c4bb557..652fa31bb5ab2 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -17,12 +17,13 @@ * under the License. */ -import React from 'react'; +import React, { useState } from 'react'; import ReactDOM from 'react-dom'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { BrowserRouter as Router, Route, withRouter, RouteComponentProps } from 'react-router-dom'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; +import { BrowserRouter as Router } from 'react-router-dom'; import { + EuiButton, EuiPage, EuiPageBody, EuiPageContent, @@ -33,61 +34,94 @@ import { EuiText, } from '@elastic/eui'; -import { AppMountContext, AppMountParameters } from '<%= relRoot %>/../src/core/public'; +import { AppMountParameters, CoreStart } from '<%= relRoot %>/../src/core/public'; -const FooApp = ({ basename, context }: { basename: string; context: AppMountContext }) => ( - - - - - -

- -

-
-
- - - -

+import { PLUGIN_NAME } from '../../common'; + +interface <%= upperCamelCaseName %>AppDeps { + basename: string; + notifications: CoreStart['notifications']; + http: CoreStart['http']; +}; + +const <%= upperCamelCaseName %>App = ({ basename, notifications, http }: <%= upperCamelCaseName %>AppDeps) => { + const [timestamp, setTimestamp] = useState(); + + const fetchData = () => { + http.get('/api/<%= snakeCase(name) %>/example').then((res) => { + setTimestamp(res.time); + notifications.toasts.addSuccess(PLUGIN_NAME); + }); + }; + + return ( + + + + + + +

-

+

-
- - -

- -

-

- -

-
-
-
-
-
-
-); + + + + +

+ +

+
+
+ + +

+ +

+

+ +

+ + + +
+
+
+ + + + + ); +}; export const renderApp = ( - context: AppMountContext, + { notifications, http }: CoreStart, + {}: any, { appBasePath, element }: AppMountParameters ) => { - ReactDOM.render(, element); + ReactDOM.render(<<%= upperCamelCaseName %>App basename={appBasePath} notifications={notifications} http={http}/>, element); return () => ReactDOM.unmountComponentAtNode(element); }; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts index 8b8e3db0e57b9..e16c4f44dee97 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/index.ts @@ -1,13 +1,10 @@ - - -import { PluginInitializerContext } from '<%= relRoot %>/src/core/public'; -export function plugin(initializerContext: PluginInitializerContext) { - return new <%= camelCaseName %>PublicPlugin(initializerContext); +export function plugin() { + return new <%= upperCamelCaseName %>PublicPlugin(); } export * from '../common'; export * from './types'; // Export plugin after all other imports -import { <%= camelCaseName %>PublicPlugin } from './plugin'; -export { <%= camelCaseName %>PublicPlugin as Plugin }; \ No newline at end of file +import { <%= upperCamelCaseName %>PublicPlugin } from './plugin'; +export { <%= upperCamelCaseName %>PublicPlugin as Plugin }; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts index 8c9f4e84a1380..cbf51b9e8b92d 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts @@ -1,34 +1,41 @@ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, AppMountContext } from '<%= relRoot %>/src/core/public'; +import { CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; import { - <%= camelCaseName %>PublicPluginSetup, - <%= camelCaseName %>PublicPluginStart, + <%= upperCamelCaseName %>PublicPluginSetup, + <%= upperCamelCaseName %>PublicPluginStart, } from './types'; +import { i18n } from '@kbn/i18n'; import { PLUGIN_NAME } from '../common'; -export class <%= camelCaseName %>PublicPlugin implements Plugin<<%= camelCaseName %>PublicPluginSetup, <%= camelCaseName %>PublicPluginStart> { - constructor(initializerContext: PluginInitializerContext) { - } - - public setup(core: CoreSetup): <%= camelCaseName %>PublicPluginSetup { +export class <%= upperCamelCaseName %>PublicPlugin implements Plugin<<%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart> { + public setup(core: CoreSetup): <%= upperCamelCaseName %>PublicPluginSetup { core.application.register({ id: '<%= camelCase(name) %>', title: PLUGIN_NAME, - async mount(context: AppMountContext, params: any) { + async mount(params) { + // Load application bundle const { renderApp } = await import('./components/app'); - return renderApp(context, params); - }, + // Get start services + const [coreStart, depsStart] = await core.getStartServices(); + return renderApp(coreStart, depsStart, params); + } }); + // Return any methods that should be available to other plugins return { getGreeting() { - return 'Hello from Plugin A!'; + return i18n.translate('<%= camelCase(name) %>.greetingText', { + defaultMessage: 'Hello from {name}!', + values: { + name: PLUGIN_NAME, + }, + }); }, }; } - public start(core: CoreStart): <%= camelCaseName %>PublicPluginStart { + public start(core: CoreStart): <%= upperCamelCaseName %>PublicPluginStart { return {} } public stop() {} -} \ No newline at end of file +} diff --git a/packages/kbn-plugin-generator/sao_template/template/public/types.ts b/packages/kbn-plugin-generator/sao_template/template/public/types.ts index b5ff60135ded0..91be6de54560f 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/types.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/types.ts @@ -1,3 +1,5 @@ -export interface <%= camelCaseName %>PublicPluginSetup {} -export interface <%= camelCaseName %>PublicPluginStart {} \ No newline at end of file +export interface <%= upperCamelCaseName %>PublicPluginSetup { + getGreeting: () => string; +} +export interface <%= upperCamelCaseName %>PublicPluginStart {} diff --git a/packages/kbn-plugin-generator/sao_template/template/server/index.ts b/packages/kbn-plugin-generator/sao_template/template/server/index.ts index b76a7b9a4116e..75ea5fe201be5 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/index.ts @@ -1,9 +1,9 @@ import { PluginInitializerContext } from '<%= relRoot %>/src/core/server'; -import { <%= camelCaseName %>ServerPlugin } from './plugin'; +import { <%= upperCamelCaseName %>ServerPlugin } from './plugin'; export function plugin(initializerContext: PluginInitializerContext) { - return new <%= camelCaseName %>ServerPlugin(initializerContext); + return new <%= upperCamelCaseName %>ServerPlugin(initializerContext); } -export { <%= camelCaseName %>ServerPlugin as Plugin }; -export * from '../common'; \ No newline at end of file +export { <%= upperCamelCaseName %>ServerPlugin as Plugin }; +export * from '../common'; diff --git a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts index 2c0eae6a99843..1a953e3add56a 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts @@ -1,13 +1,30 @@ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/server'; -export interface <%= camelCaseName %>PluginSetup {}; -export interface <%= camelCaseName %>PluginStart {}; +import { + <%= upperCamelCaseName %>PluginSetup, + <%= upperCamelCaseName %>PluginStart, +} from './types'; -export class <%= camelCaseName %>ServerPlugin implements Plugin<<%= camelCaseName %>PluginSetup, <%= camelCaseName %>PluginStart> { +export class <%= upperCamelCaseName %>ServerPlugin implements Plugin<<%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart> { constructor(initializerContext: PluginInitializerContext) {} public setup(core: CoreSetup) { + const router = core.http.createRouter(); + + router.get( + { + path: '/api/<%= snakeCase(name) %>/example', + validate: false, + }, + async (context, request, response) => { + return response.ok({ + body: { + time: (new Date()).toISOString(), + } + }); + } + ); return {}; } @@ -18,4 +35,4 @@ export class <%= camelCaseName %>ServerPlugin implements Plugin<<%= camelCaseNam public stop() {} } -export { <%= camelCaseName %>ServerPlugin as Plugin }; \ No newline at end of file +export { <%= upperCamelCaseName %>ServerPlugin as Plugin }; diff --git a/packages/kbn-plugin-generator/sao_template/template/server/types.ts b/packages/kbn-plugin-generator/sao_template/template/server/types.ts new file mode 100644 index 0000000000000..dec2be66869c2 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/server/types.ts @@ -0,0 +1,2 @@ +export interface <%= upperCamelCaseName %>PluginSetup {}; +export interface <%= upperCamelCaseName %>PluginStart {}; From fed27b5e455544437fbc2d379f444e7821e31fb4 Mon Sep 17 00:00:00 2001 From: Liza K Date: Mon, 20 Jan 2020 18:37:42 +0200 Subject: [PATCH 06/23] Added navigation --- .../sao_template/template/kibana.json | 2 +- .../template/public/components/app.tsx | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/template/kibana.json b/packages/kbn-plugin-generator/sao_template/template/kibana.json index 1d8473bdcf34c..f8bb07040abeb 100644 --- a/packages/kbn-plugin-generator/sao_template/template/kibana.json +++ b/packages/kbn-plugin-generator/sao_template/template/kibana.json @@ -3,6 +3,6 @@ "version": "<%= kbnVersion %>", "server": <%= hasServer %>, "ui": <%= hasUi %>, - "requiredPlugins": [], + "requiredPlugins": ["navigation"], "optionalPlugins": [] } diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index 652fa31bb5ab2..a01b4f2af113f 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -35,18 +35,19 @@ import { } from '@elastic/eui'; import { AppMountParameters, CoreStart } from '<%= relRoot %>/../src/core/public'; +import { NavigationPublicPluginStart } from '<%= relRoot %>/../src/plugins/navigation/public'; -import { PLUGIN_NAME } from '../../common'; +import { PLUGIN_ID, PLUGIN_NAME } from '../../common'; interface <%= upperCamelCaseName %>AppDeps { basename: string; notifications: CoreStart['notifications']; http: CoreStart['http']; + navigation: NavigationPublicPluginStart; }; -const <%= upperCamelCaseName %>App = ({ basename, notifications, http }: <%= upperCamelCaseName %>AppDeps) => { +const <%= upperCamelCaseName %>App = ({ basename, notifications, http, navigation }: <%= upperCamelCaseName %>AppDeps) => { const [timestamp, setTimestamp] = useState(); - const fetchData = () => { http.get('/api/<%= snakeCase(name) %>/example').then((res) => { setTimestamp(res.time); @@ -57,6 +58,10 @@ const <%= upperCamelCaseName %>App = ({ basename, notifications, http }: <%= upp return ( + @@ -118,10 +123,10 @@ const <%= upperCamelCaseName %>App = ({ basename, notifications, http }: <%= upp export const renderApp = ( { notifications, http }: CoreStart, - {}: any, + { navigation }: any, { appBasePath, element }: AppMountParameters ) => { - ReactDOM.render(<<%= upperCamelCaseName %>App basename={appBasePath} notifications={notifications} http={http}/>, element); + ReactDOM.render(<<%= upperCamelCaseName %>App basename={appBasePath} notifications={notifications} http={http} navigation={navigation}/>, element); return () => ReactDOM.unmountComponentAtNode(element); }; From 7dbb58570ae395ecd8475367048b3f6496581955 Mon Sep 17 00:00:00 2001 From: Liza K Date: Mon, 20 Jan 2020 18:38:22 +0200 Subject: [PATCH 07/23] add empty element --- .../template/public/components/app.tsx | 110 +++++++++--------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index a01b4f2af113f..0783a7300a8a4 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -58,64 +58,66 @@ const <%= upperCamelCaseName %>App = ({ basename, notifications, http, navigatio return ( - - - - - -

- -

-
-
- - - -

+ <> + + + + + +

-

+

-
- - -

- -

-

- + + + +

+ -

- - - - - - - - +

+ + + + +

+ +

+

+ +

+ + + +
+
+
+
+
+
); From 3f8520ad4c0580e6e714f51a424752392af898dd Mon Sep 17 00:00:00 2001 From: Liza K Date: Tue, 21 Jan 2020 13:24:43 +0200 Subject: [PATCH 08/23] eslint --- .../integration_tests/generate_plugin.test.js | 2 +- .../kbn-plugin-generator/sao_template/sao.js | 40 ++++++--------- .../sao_template/template/eslintrc.js | 9 ++++ .../template/public/components/app.tsx | 51 +++++++++++-------- .../sao_template/template/public/plugin.ts | 27 +++++----- .../sao_template/template/public/types.ts | 4 +- .../sao_template/template/server/plugin.ts | 14 +++-- .../sao_template/template/server/types.ts | 6 ++- 8 files changed, 82 insertions(+), 71 deletions(-) create mode 100644 packages/kbn-plugin-generator/sao_template/template/eslintrc.js diff --git a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js index aa6611f3b6738..ce9d4c001df61 100644 --- a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js +++ b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js @@ -61,7 +61,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug expect(stats.isDirectory()).toBe(true); }); - it(`should create an internationalization config file with a blank line appended to satisfy the parser`, async () => { + it.skip(`should create an internationalization config file with a blank line appended to satisfy the parser`, async () => { // Link to the error that happens when the blank line is not there: // https://github.com/elastic/kibana/pull/45044#issuecomment-530092627 const intlFile = `${generatedPath}/.i18nrc.json`; diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index bde118c69149e..86d9208e9eee2 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -23,6 +23,7 @@ const startCase = require('lodash.startcase'); const camelCase = require('lodash.camelcase'); const snakeCase = require('lodash.snakecase'); const chalk = require('chalk'); +const execa = require('execa'); const pkg = require('../package.json'); const kibanaPkgPath = require.resolve('../../../package.json'); @@ -44,14 +45,14 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { message: 'Should an app component be generated?', default: true, }, - generateTranslations: { + generateApi: { type: 'confirm', - message: 'Should translation files be generated?', + message: 'Should a server API be generated?', default: true, }, - generateApi: { + generateTranslations: { type: 'confirm', - message: 'Should a server API be generated?', + message: 'Should translation files be generated?', default: true, }, generateScss: { @@ -63,16 +64,12 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { }, filters: { 'public/**/*': 'generateApp', + 'server/**/*': 'generateApi', 'translations/**/*': 'generateTranslations', '.i18nrc.json': 'generateTranslations', - 'server/**/*': 'generateApi', - 'public/app.scss': 'generateScss', - '.kibana-plugin-helpers.json': 'generateScss', }, move: { - gitignore: '.gitignore', 'eslintrc.js': '.eslintrc.js', - 'package_template.json': 'package.json', }, data: answers => Object.assign( @@ -82,6 +79,7 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { camelCase, snakeCase, name, + isKibanaPlugin, kbnVersion: answers.kbnVersion, upperCamelCaseName: name.charAt(0).toUpperCase() + camelCase(name).slice(1), hasUi: !!answers.generateApp, @@ -94,27 +92,21 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { installDependencies: false, gitInit: !isKibanaPlugin, async post({ log }) { - // await execa('yarn', ['kbn', 'bootstrap'], { - // cwd: KBN_DIR, - // stdio: 'inherit', - // }); - const dir = relative(process.cwd(), targetPath); - // try { - // await execa('yarn', ['lint', '--fix'], { - // cwd: dir, - // all: true, - // }); - // } catch (error) { - // throw new Error(`Failure when running prettier on the generated output: ${error.all}`); - // } + // Apply eslint to the generated plugin + try { + await execa('yarn', ['lint:es', `./${dir}/**/*.ts*`, '--no-ignore', '--fix']); + } catch (error) { + throw new Error( + `Failure when running prettier on the generated output: ${error.all || error}` + ); + } log.success(chalk`🎉 -Your plugin has been created in {bold ${dir}}. Move into that directory to run it: +Your plugin has been created in {bold ${dir}}. - {bold cd "${dir}"} {bold yarn start} `); }, diff --git a/packages/kbn-plugin-generator/sao_template/template/eslintrc.js b/packages/kbn-plugin-generator/sao_template/template/eslintrc.js new file mode 100644 index 0000000000000..b68d42e32e047 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/eslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + root: true, + extends: ['@elastic/eslint-config-kibana', 'plugin:@elastic/eui/recommended'], + <%_ if (!isKibanaPlugin) { -%> + rules: { + "@kbn/eslint/require-license-header": "off" + } + <%_ } -%> +}; \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index 0783a7300a8a4..78ded1c110ae4 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -39,30 +39,38 @@ import { NavigationPublicPluginStart } from '<%= relRoot %>/../src/plugins/navig import { PLUGIN_ID, PLUGIN_NAME } from '../../common'; -interface <%= upperCamelCaseName %>AppDeps { +interface <%= upperCamelCaseName %>AppDeps { basename: string; notifications: CoreStart['notifications']; http: CoreStart['http']; navigation: NavigationPublicPluginStart; -}; +} const <%= upperCamelCaseName %>App = ({ basename, notifications, http, navigation }: <%= upperCamelCaseName %>AppDeps) => { + // Use React hooks to manage state. const [timestamp, setTimestamp] = useState(); - const fetchData = () => { - http.get('/api/<%= snakeCase(name) %>/example').then((res) => { + + const onClickHandler = () => { +<%_ if (generateApi) { -%> + // Use the core http service to make a response to the server API. + http.get('/api/<%= snakeCase(name) %>/example').then(res => { setTimestamp(res.time); + // Use the core notifications service to display a success message. notifications.toasts.addSuccess(PLUGIN_NAME); }); +<%_ } else { -%> + setTimestamp(new Date().toISOString()); + notifications.toasts.addSuccess(PLUGIN_NAME); +<%_ } -%> }; + // Render the application DOM. + // Note that `navigation.ui.TopNavMenu` is a stateful component exported on the `navigation` plugin's start contract. return ( <> - + @@ -97,20 +105,13 @@ const <%= upperCamelCaseName %>App = ({ basename, notifications, http, navigatio

-

- - +

+ + @@ -128,7 +129,15 @@ export const renderApp = ( { navigation }: any, { appBasePath, element }: AppMountParameters ) => { - ReactDOM.render(<<%= upperCamelCaseName %>App basename={appBasePath} notifications={notifications} http={http} navigation={navigation}/>, element); + ReactDOM.render( + <<%= upperCamelCaseName %>App + basename={appBasePath} + notifications={notifications} + http={http} + navigation={navigation} + />, + element + ); return () => ReactDOM.unmountComponentAtNode(element); }; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts index cbf51b9e8b92d..93a13b4c68ce2 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts @@ -1,41 +1,42 @@ -import { CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; -import { - <%= upperCamelCaseName %>PublicPluginSetup, - <%= upperCamelCaseName %>PublicPluginStart, -} from './types'; import { i18n } from '@kbn/i18n'; +import { CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; +import { <%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart } from './types'; import { PLUGIN_NAME } from '../common'; -export class <%= upperCamelCaseName %>PublicPlugin implements Plugin<<%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart> { +export class <%= upperCamelCaseName %>PublicPlugin + implements Plugin<<%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart> { public setup(core: CoreSetup): <%= upperCamelCaseName %>PublicPluginSetup { + + // Register an application into the side navigation menu core.application.register({ id: '<%= camelCase(name) %>', title: PLUGIN_NAME, async mount(params) { // Load application bundle const { renderApp } = await import('./components/app'); - // Get start services + // Get start services as specified in kibana.json const [coreStart, depsStart] = await core.getStartServices(); + // Render the application return renderApp(coreStart, depsStart, params); - } + }, }); - // Return any methods that should be available to other plugins + // Return methods that should be available to other plugins return { getGreeting() { return i18n.translate('<%= camelCase(name) %>.greetingText', { defaultMessage: 'Hello from {name}!', - values: { + values: { name: PLUGIN_NAME, - }, + }, }); }, }; } public start(core: CoreStart): <%= upperCamelCaseName %>PublicPluginStart { - return {} - } + return {}; + } public stop() {} } diff --git a/packages/kbn-plugin-generator/sao_template/template/public/types.ts b/packages/kbn-plugin-generator/sao_template/template/public/types.ts index 91be6de54560f..5a8a6b9f4431d 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/types.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/types.ts @@ -1,5 +1,5 @@ - export interface <%= upperCamelCaseName %>PublicPluginSetup { - getGreeting: () => string; + getGreeting: () => string; } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface <%= upperCamelCaseName %>PublicPluginStart {} diff --git a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts index 1a953e3add56a..42a97896e32e8 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts @@ -1,17 +1,15 @@ - import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/server'; -import { - <%= upperCamelCaseName %>PluginSetup, - <%= upperCamelCaseName %>PluginStart, -} from './types'; +import { <%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart } from './types'; -export class <%= upperCamelCaseName %>ServerPlugin implements Plugin<<%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart> { +export class <%= upperCamelCaseName %>ServerPlugin + implements Plugin<<%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart> { constructor(initializerContext: PluginInitializerContext) {} public setup(core: CoreSetup) { const router = core.http.createRouter(); + // Register a server side API endpoint router.get( { path: '/api/<%= snakeCase(name) %>/example', @@ -20,8 +18,8 @@ export class <%= upperCamelCaseName %>ServerPlugin implements Plugin<<%= upperCa async (context, request, response) => { return response.ok({ body: { - time: (new Date()).toISOString(), - } + time: new Date().toISOString(), + }, }); } ); diff --git a/packages/kbn-plugin-generator/sao_template/template/server/types.ts b/packages/kbn-plugin-generator/sao_template/template/server/types.ts index dec2be66869c2..adbc5e93f03c5 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/types.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/types.ts @@ -1,2 +1,4 @@ -export interface <%= upperCamelCaseName %>PluginSetup {}; -export interface <%= upperCamelCaseName %>PluginStart {}; +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface <%= upperCamelCaseName %>PluginSetup {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface <%= upperCamelCaseName %>PluginStart {} From 7f5e3638cd30675e74796d08bd051f49443cf9a9 Mon Sep 17 00:00:00 2001 From: Liza K Date: Thu, 23 Jan 2020 14:50:43 +0200 Subject: [PATCH 09/23] platform team CR --- .../kbn-plugin-generator/sao_template/sao.js | 1 + .../template/public/application.tsx | 25 +++++++++++++++++ .../template/public/components/app.tsx | 21 +------------- .../sao_template/template/public/index.ts | 5 ++-- .../sao_template/template/public/plugin.ts | 8 +++--- .../sao_template/template/public/types.ts | 6 ++++ .../sao_template/template/server/plugin.ts | 28 ++++++++----------- .../template/server/routes/index.ts | 17 +++++++++++ 8 files changed, 68 insertions(+), 43 deletions(-) create mode 100644 packages/kbn-plugin-generator/sao_template/template/public/application.tsx create mode 100644 packages/kbn-plugin-generator/sao_template/template/server/routes/index.ts diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index 86d9208e9eee2..b72cb1487e03e 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -98,6 +98,7 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { try { await execa('yarn', ['lint:es', `./${dir}/**/*.ts*`, '--no-ignore', '--fix']); } catch (error) { + console.error(error); throw new Error( `Failure when running prettier on the generated output: ${error.all || error}` ); diff --git a/packages/kbn-plugin-generator/sao_template/template/public/application.tsx b/packages/kbn-plugin-generator/sao_template/template/public/application.tsx new file mode 100644 index 0000000000000..581d414c0a578 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/public/application.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { AppMountParameters, CoreStart } from '<%= relRoot %>/src/core/public'; +import { AppPluginDependencies } from './types'; +import { <%= upperCamelCaseName %>App } from './components/app'; + + +export const renderApp = ( + { notifications, http }: CoreStart, + { navigation }: AppPluginDependencies, + { appBasePath, element }: AppMountParameters + ) => { + ReactDOM.render( + <<%= upperCamelCaseName %>App + basename={appBasePath} + notifications={notifications} + http={http} + navigation={navigation} + />, + element + ); + + return () => ReactDOM.unmountComponentAtNode(element); + }; + \ No newline at end of file diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index 78ded1c110ae4..e0449375c39d1 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -18,7 +18,6 @@ */ import React, { useState } from 'react'; -import ReactDOM from 'react-dom'; import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import { BrowserRouter as Router } from 'react-router-dom'; @@ -46,7 +45,7 @@ interface <%= upperCamelCaseName %>AppDeps { navigation: NavigationPublicPluginStart; } -const <%= upperCamelCaseName %>App = ({ basename, notifications, http, navigation }: <%= upperCamelCaseName %>AppDeps) => { +export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, navigation }: <%= upperCamelCaseName %>AppDeps) => { // Use React hooks to manage state. const [timestamp, setTimestamp] = useState(); @@ -123,21 +122,3 @@ const <%= upperCamelCaseName %>App = ({ basename, notifications, http, navigatio
); }; - -export const renderApp = ( - { notifications, http }: CoreStart, - { navigation }: any, - { appBasePath, element }: AppMountParameters -) => { - ReactDOM.render( - <<%= upperCamelCaseName %>App - basename={appBasePath} - notifications={notifications} - http={http} - navigation={navigation} - />, - element - ); - - return () => ReactDOM.unmountComponentAtNode(element); -}; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts index e16c4f44dee97..10db6e2ff01bd 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/index.ts @@ -1,3 +1,5 @@ + +import { <%= upperCamelCaseName %>PublicPlugin } from './plugin'; export function plugin() { return new <%= upperCamelCaseName %>PublicPlugin(); } @@ -5,6 +7,3 @@ export function plugin() { export * from '../common'; export * from './types'; -// Export plugin after all other imports -import { <%= upperCamelCaseName %>PublicPlugin } from './plugin'; -export { <%= upperCamelCaseName %>PublicPlugin as Plugin }; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts index 93a13b4c68ce2..3e359d74661b3 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts @@ -1,23 +1,23 @@ import { i18n } from '@kbn/i18n'; import { CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; -import { <%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart } from './types'; +import { <%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart, AppPluginDependencies } from './types'; import { PLUGIN_NAME } from '../common'; export class <%= upperCamelCaseName %>PublicPlugin implements Plugin<<%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart> { + public setup(core: CoreSetup): <%= upperCamelCaseName %>PublicPluginSetup { - // Register an application into the side navigation menu core.application.register({ id: '<%= camelCase(name) %>', title: PLUGIN_NAME, async mount(params) { // Load application bundle - const { renderApp } = await import('./components/app'); + const { renderApp } = await import('./application'); // Get start services as specified in kibana.json const [coreStart, depsStart] = await core.getStartServices(); // Render the application - return renderApp(coreStart, depsStart, params); + return renderApp(coreStart, depsStart as AppPluginDependencies, params); }, }); diff --git a/packages/kbn-plugin-generator/sao_template/template/public/types.ts b/packages/kbn-plugin-generator/sao_template/template/public/types.ts index 5a8a6b9f4431d..480f93aa2df78 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/types.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/types.ts @@ -1,5 +1,11 @@ +import { NavigationPublicPluginStart } from '<%= relRoot %>/src/plugins/navigation/public'; + export interface <%= upperCamelCaseName %>PublicPluginSetup { getGreeting: () => string; } // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface <%= upperCamelCaseName %>PublicPluginStart {} + +export interface AppPluginDependencies { + navigation: NavigationPublicPluginStart +}; diff --git a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts index 42a97896e32e8..c380a46ef648a 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts @@ -1,32 +1,28 @@ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/server'; +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '<%= relRoot %>/src/core/server'; import { <%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart } from './types'; +import { defineRoutes } from './routes'; export class <%= upperCamelCaseName %>ServerPlugin implements Plugin<<%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart> { - constructor(initializerContext: PluginInitializerContext) {} + private readonly logger: Logger; + constructor(initializerContext: PluginInitializerContext) { + this.logger = initializerContext.logger.get(); + } + public setup(core: CoreSetup) { + this.logger.debug('<%= name %>: Ssetup'); const router = core.http.createRouter(); - // Register a server side API endpoint - router.get( - { - path: '/api/<%= snakeCase(name) %>/example', - validate: false, - }, - async (context, request, response) => { - return response.ok({ - body: { - time: new Date().toISOString(), - }, - }); - } - ); + // Register server side APIs + defineRoutes(router); + return {}; } public start(core: CoreStart) { + this.logger.debug('<%= name %>: Started'); return {}; } diff --git a/packages/kbn-plugin-generator/sao_template/template/server/routes/index.ts b/packages/kbn-plugin-generator/sao_template/template/server/routes/index.ts new file mode 100644 index 0000000000000..d8bb00f0dea6c --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/server/routes/index.ts @@ -0,0 +1,17 @@ +import { IRouter } from '<%= relRoot %>/../src/core/server'; + +export function defineRoutes(router: IRouter) { + router.get( + { + path: '/api/<%= snakeCase(name) %>/example', + validate: false, + }, + async (context, request, response) => { + return response.ok({ + body: { + time: new Date().toISOString(), + }, + }); + } + ); +} From 7ad1324d74a8f3154fadcf0561a1fc9e7b119b28 Mon Sep 17 00:00:00 2001 From: Liza K Date: Thu, 23 Jan 2020 16:07:00 +0200 Subject: [PATCH 10/23] design CR improvements --- .../template/public/components/app.tsx | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index e0449375c39d1..2e448c47f3cee 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -18,11 +18,13 @@ */ import React, { useState } from 'react'; +import { i18n } from '@kbn/i18n'; import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import { BrowserRouter as Router } from 'react-router-dom'; import { EuiButton, + EuiHorizontalRule, EuiPage, EuiPageBody, EuiPageContent, @@ -55,7 +57,9 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na http.get('/api/<%= snakeCase(name) %>/example').then(res => { setTimestamp(res.time); // Use the core notifications service to display a success message. - notifications.toasts.addSuccess(PLUGIN_NAME); + notifications.toasts.addSuccess(i18n.translate('banana.dataUpdated', { + defaultMessage: 'Data updated', + })); }); <%_ } else { -%> setTimestamp(new Date().toISOString()); @@ -70,14 +74,14 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na <> - +

@@ -89,19 +93,20 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na

-

+

-

+

+

Date: Sun, 26 Jan 2020 16:47:19 +0200 Subject: [PATCH 11/23] text updates --- .../sao_template/template/public/components/app.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index 2e448c47f3cee..a5accc84f06ae 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -81,7 +81,7 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na

@@ -93,7 +93,7 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na

@@ -115,7 +115,7 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na />

- +
From 33c2680972c4305e7f42d2693ed82195cc8fcb45 Mon Sep 17 00:00:00 2001 From: Liza K Date: Sun, 26 Jan 2020 17:17:22 +0200 Subject: [PATCH 12/23] temp disable plugin gen tests --- .../integration_tests/generate_plugin.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js index ce9d4c001df61..2c9266c712b2c 100644 --- a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js +++ b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js @@ -78,7 +78,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug }); }); - it(`'yarn test:server' should exit 0`, async () => { + it.skip(`'yarn test:server' should exit 0`, async () => { await execa('yarn', ['test:server'], { cwd: generatedPath, env: { @@ -87,7 +87,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug }); }); - it(`'yarn build' should exit 0`, async () => { + it.skip(`'yarn build' should exit 0`, async () => { await execa('yarn', ['build'], { cwd: generatedPath }); }); @@ -98,7 +98,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug beforeAll(es.start); afterAll(es.stop); - it(`'yarn start' should result in the spec plugin being initialized on kibana's stdout`, async () => { + it.skip(`'yarn start' should result in the spec plugin being initialized on kibana's stdout`, async () => { await withProcRunner(log, async proc => { await proc.run('kibana', { cmd: 'yarn', @@ -120,7 +120,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug await execa('yarn', ['preinstall'], { cwd: generatedPath }); }); - it(`'yarn lint' should exit 0`, async () => { + it.skip(`'yarn lint' should exit 0`, async () => { await execa('yarn', ['lint'], { cwd: generatedPath }); }); From 0dfa19f623929b11b3338d1ec6fc41a473ae2fc7 Mon Sep 17 00:00:00 2001 From: Liza K Date: Wed, 29 Jan 2020 16:28:10 +0200 Subject: [PATCH 13/23] eslint --- .../kbn-plugin-generator/sao_template/template/public/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts index 10db6e2ff01bd..cdb5cc8d490e3 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/index.ts @@ -1,5 +1,5 @@ - import { <%= upperCamelCaseName %>PublicPlugin } from './plugin'; + export function plugin() { return new <%= upperCamelCaseName %>PublicPlugin(); } From 47b7beffd774bec0dcdd3f560710185241e22168 Mon Sep 17 00:00:00 2001 From: Liza K Date: Wed, 29 Jan 2020 18:16:12 +0200 Subject: [PATCH 14/23] Code review fixes --- .../sao_template/template/public/components/app.tsx | 6 +++--- .../sao_template/template/public/plugin.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index a5accc84f06ae..913400efc0b10 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -35,7 +35,7 @@ import { EuiText, } from '@elastic/eui'; -import { AppMountParameters, CoreStart } from '<%= relRoot %>/../src/core/public'; +import { CoreStart } from '<%= relRoot %>/../src/core/public'; import { NavigationPublicPluginStart } from '<%= relRoot %>/../src/plugins/navigation/public'; import { PLUGIN_ID, PLUGIN_NAME } from '../../common'; @@ -103,13 +103,13 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na

diff --git a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts index 3e359d74661b3..ec1983aa58821 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts @@ -1,5 +1,5 @@ import { i18n } from '@kbn/i18n'; -import { CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; +import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; import { <%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart, AppPluginDependencies } from './types'; import { PLUGIN_NAME } from '../common'; @@ -11,7 +11,7 @@ export class <%= upperCamelCaseName %>PublicPlugin core.application.register({ id: '<%= camelCase(name) %>', title: PLUGIN_NAME, - async mount(params) { + async mount(params: AppMountParameters) { // Load application bundle const { renderApp } = await import('./application'); // Get start services as specified in kibana.json From 38aee60825afbef5bd97f6e3c9f27665f0d0725e Mon Sep 17 00:00:00 2001 From: Liza K Date: Wed, 29 Jan 2020 18:23:40 +0200 Subject: [PATCH 15/23] Add scss support - requires #53976 to be merged to work --- packages/kbn-plugin-generator/sao_template/sao.js | 2 ++ .../sao_template/template/public/index.scss | 0 .../sao_template/template/public/index.ts | 4 ++++ 3 files changed, 6 insertions(+) create mode 100644 packages/kbn-plugin-generator/sao_template/template/public/index.scss diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index b72cb1487e03e..53d7089e43ffa 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -63,6 +63,7 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { }, }, filters: { + 'public/**/index.scss': 'generateScss', 'public/**/*': 'generateApp', 'server/**/*': 'generateApi', 'translations/**/*': 'generateTranslations', @@ -84,6 +85,7 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { upperCamelCaseName: name.charAt(0).toUpperCase() + camelCase(name).slice(1), hasUi: !!answers.generateApp, hasServer: !!answers.generateApi, + hasScss: !!answers.generateScss, relRoot: isKibanaPlugin ? '../../../..' : '../../..', }, answers diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.scss b/packages/kbn-plugin-generator/sao_template/template/public/index.scss new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts index cdb5cc8d490e3..6b769e873335f 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/index.ts @@ -1,3 +1,7 @@ +<%_ if (hasScss) { -%> +import './index.scss'; +<%_ } -%> + import { <%= upperCamelCaseName %>PublicPlugin } from './plugin'; export function plugin() { From a9d471bb5fd60589664beb51d680f1e5f24dabf3 Mon Sep 17 00:00:00 2001 From: Liza K Date: Thu, 30 Jan 2020 12:13:50 +0200 Subject: [PATCH 16/23] CR fixes --- .../sao_template/template/README.md | 2 +- .../sao_template/template/public/components/app.tsx | 2 +- .../sao_template/template/public/index.ts | 12 +++++++----- .../sao_template/template/public/plugin.ts | 10 +++++----- .../sao_template/template/public/types.ts | 4 ++-- .../sao_template/template/server/index.ts | 11 +++++++---- .../sao_template/template/server/plugin.ts | 6 ++---- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/template/README.md b/packages/kbn-plugin-generator/sao_template/template/README.md index acd1ede5a573e..13dfab2eb3f01 100755 --- a/packages/kbn-plugin-generator/sao_template/template/README.md +++ b/packages/kbn-plugin-generator/sao_template/template/README.md @@ -8,5 +8,5 @@ ## development -See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment. Once you have completed that, use the following yarn scripts. +See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment. diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index 913400efc0b10..d6a79906d37b9 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -103,7 +103,7 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na

diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts index 6b769e873335f..9f788de48d90c 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/index.ts @@ -2,12 +2,14 @@ import './index.scss'; <%_ } -%> -import { <%= upperCamelCaseName %>PublicPlugin } from './plugin'; +import { <%= upperCamelCaseName %>Plugin } from './plugin'; +// These exports are the public contract for your static code and types. export function plugin() { - return new <%= upperCamelCaseName %>PublicPlugin(); + return new <%= upperCamelCaseName %>Plugin(); } - -export * from '../common'; -export * from './types'; +export { + <%= upperCamelCaseName %>PluginSetup, + <%= upperCamelCaseName %>PluginStart, +} from './types'; diff --git a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts index ec1983aa58821..cc46e1cf0c1d7 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts @@ -1,12 +1,12 @@ import { i18n } from '@kbn/i18n'; import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; -import { <%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart, AppPluginDependencies } from './types'; +import { <%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart, AppPluginDependencies } from './types'; import { PLUGIN_NAME } from '../common'; -export class <%= upperCamelCaseName %>PublicPlugin - implements Plugin<<%= upperCamelCaseName %>PublicPluginSetup, <%= upperCamelCaseName %>PublicPluginStart> { +export class <%= upperCamelCaseName %>Plugin + implements Plugin<<%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart> { - public setup(core: CoreSetup): <%= upperCamelCaseName %>PublicPluginSetup { + public setup(core: CoreSetup): <%= upperCamelCaseName %>PluginSetup { // Register an application into the side navigation menu core.application.register({ id: '<%= camelCase(name) %>', @@ -34,7 +34,7 @@ export class <%= upperCamelCaseName %>PublicPlugin }; } - public start(core: CoreStart): <%= upperCamelCaseName %>PublicPluginStart { + public start(core: CoreStart): <%= upperCamelCaseName %>PluginStart { return {}; } diff --git a/packages/kbn-plugin-generator/sao_template/template/public/types.ts b/packages/kbn-plugin-generator/sao_template/template/public/types.ts index 480f93aa2df78..43d2c38bffd86 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/types.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/types.ts @@ -1,10 +1,10 @@ import { NavigationPublicPluginStart } from '<%= relRoot %>/src/plugins/navigation/public'; -export interface <%= upperCamelCaseName %>PublicPluginSetup { +export interface <%= upperCamelCaseName %>PluginSetup { getGreeting: () => string; } // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface <%= upperCamelCaseName %>PublicPluginStart {} +export interface <%= upperCamelCaseName %>PluginStart {} export interface AppPluginDependencies { navigation: NavigationPublicPluginStart diff --git a/packages/kbn-plugin-generator/sao_template/template/server/index.ts b/packages/kbn-plugin-generator/sao_template/template/server/index.ts index 75ea5fe201be5..2305e0aba28bb 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/index.ts @@ -1,9 +1,12 @@ import { PluginInitializerContext } from '<%= relRoot %>/src/core/server'; -import { <%= upperCamelCaseName %>ServerPlugin } from './plugin'; +import { <%= upperCamelCaseName %>Plugin } from './plugin'; +// These exports are the server side contract for your static code and types. export function plugin(initializerContext: PluginInitializerContext) { - return new <%= upperCamelCaseName %>ServerPlugin(initializerContext); + return new <%= upperCamelCaseName %>Plugin(initializerContext); } -export { <%= upperCamelCaseName %>ServerPlugin as Plugin }; -export * from '../common'; +export { + <%= upperCamelCaseName %>PluginSetup, + <%= upperCamelCaseName %>PluginStart, +} from './types'; diff --git a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts index c380a46ef648a..d6a343209e39e 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/plugin.ts @@ -3,7 +3,7 @@ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from ' import { <%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart } from './types'; import { defineRoutes } from './routes'; -export class <%= upperCamelCaseName %>ServerPlugin +export class <%= upperCamelCaseName %>Plugin implements Plugin<<%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart> { private readonly logger: Logger; @@ -12,7 +12,7 @@ export class <%= upperCamelCaseName %>ServerPlugin } public setup(core: CoreSetup) { - this.logger.debug('<%= name %>: Ssetup'); + this.logger.debug('<%= name %>: Setup'); const router = core.http.createRouter(); // Register server side APIs @@ -28,5 +28,3 @@ export class <%= upperCamelCaseName %>ServerPlugin public stop() {} } - -export { <%= upperCamelCaseName %>ServerPlugin as Plugin }; From 5e3f3dc697f22cd7c077abfa6b305875d28c0281 Mon Sep 17 00:00:00 2001 From: Liza K Date: Thu, 30 Jan 2020 14:28:33 +0200 Subject: [PATCH 17/23] comment fixes --- .../kbn-plugin-generator/sao_template/template/README.md | 2 +- .../sao_template/template/public/index.ts | 5 ++++- .../sao_template/template/server/index.ts | 7 +++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/template/README.md b/packages/kbn-plugin-generator/sao_template/template/README.md index 13dfab2eb3f01..1e0139428fcbc 100755 --- a/packages/kbn-plugin-generator/sao_template/template/README.md +++ b/packages/kbn-plugin-generator/sao_template/template/README.md @@ -6,7 +6,7 @@ --- -## development +## Development See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment. diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts index 9f788de48d90c..246b5aca73cce 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/index.ts @@ -4,7 +4,10 @@ import './index.scss'; import { <%= upperCamelCaseName %>Plugin } from './plugin'; -// These exports are the public contract for your static code and types. +/** + * This exports static code and TypeScript types, + * as well as, Kibana Platform `plugin()` initializer. + **/ export function plugin() { return new <%= upperCamelCaseName %>Plugin(); } diff --git a/packages/kbn-plugin-generator/sao_template/template/server/index.ts b/packages/kbn-plugin-generator/sao_template/template/server/index.ts index 2305e0aba28bb..f34203722e0cc 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/index.ts @@ -1,8 +1,11 @@ import { PluginInitializerContext } from '<%= relRoot %>/src/core/server'; import { <%= upperCamelCaseName %>Plugin } from './plugin'; -// These exports are the server side contract for your static code and types. -export function plugin(initializerContext: PluginInitializerContext) { +/** + * This exports static code and TypeScript types, + * as well as, Kibana Platform `plugin()` initializer. + **/ + export function plugin(initializerContext: PluginInitializerContext) { return new <%= upperCamelCaseName %>Plugin(initializerContext); } From b91ee61b442737cd02116e511ef96739c28c804f Mon Sep 17 00:00:00 2001 From: Liza K Date: Thu, 30 Jan 2020 14:47:12 +0200 Subject: [PATCH 18/23] Don't generate eslint for internal plugins by default --- packages/kbn-plugin-generator/sao_template/sao.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index 53d7089e43ffa..168fb78d56e83 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -61,6 +61,11 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { when: answers => answers.generateApp, default: true, }, + generateEslint: { + type: 'confirm', + message: 'Should generate custom eslint file be used?', + default: !isKibanaPlugin, + }, }, filters: { 'public/**/index.scss': 'generateScss', @@ -68,6 +73,7 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { 'server/**/*': 'generateApi', 'translations/**/*': 'generateTranslations', '.i18nrc.json': 'generateTranslations', + 'eslintrc.js': 'generateEslint', }, move: { 'eslintrc.js': '.eslintrc.js', From 09b237560eb514f470ce992d35911f3fe1db92d1 Mon Sep 17 00:00:00 2001 From: Liza K Date: Thu, 30 Jan 2020 15:24:14 +0200 Subject: [PATCH 19/23] Update tests --- .../integration_tests/generate_plugin.test.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js index 2c9266c712b2c..7cacfcf93937b 100644 --- a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js +++ b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js @@ -61,6 +61,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug expect(stats.isDirectory()).toBe(true); }); + // skipped until internationalization is re-introduced it.skip(`should create an internationalization config file with a blank line appended to satisfy the parser`, async () => { // Link to the error that happens when the blank line is not there: // https://github.com/elastic/kibana/pull/45044#issuecomment-530092627 @@ -78,15 +79,6 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug }); }); - it.skip(`'yarn test:server' should exit 0`, async () => { - await execa('yarn', ['test:server'], { - cwd: generatedPath, - env: { - DISABLE_JUNIT_REPORTER: '1', - }, - }); - }); - it.skip(`'yarn build' should exit 0`, async () => { await execa('yarn', ['build'], { cwd: generatedPath }); }); @@ -98,7 +90,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug beforeAll(es.start); afterAll(es.stop); - it.skip(`'yarn start' should result in the spec plugin being initialized on kibana's stdout`, async () => { + it(`'yarn start' should result in the spec plugin being initialized on kibana's stdout`, async () => { await withProcRunner(log, async proc => { await proc.run('kibana', { cmd: 'yarn', @@ -109,7 +101,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug '--migrations.skip=true', ], cwd: generatedPath, - wait: /ispec_plugin.+Status changed from uninitialized to green - Ready/, + wait: /ispec_plugin.+Setting up plugin/, }); await proc.stop('kibana'); }); From 2a9e1ff04d87c3b775305cf0964928469d519a8e Mon Sep 17 00:00:00 2001 From: Liza K Date: Thu, 30 Jan 2020 15:50:22 +0200 Subject: [PATCH 20/23] reenable jest test for sao --- .../sao_template/sao.test.js | 56 ++++--------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/sao.test.js b/packages/kbn-plugin-generator/sao_template/sao.test.js index e353bb2be6c0b..0dbdb7d3c097b 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.test.js +++ b/packages/kbn-plugin-generator/sao_template/sao.test.js @@ -19,8 +19,6 @@ const sao = require('sao'); -const templatePkg = require('../package.json'); - const template = { fromPath: __dirname, configOptions: { @@ -32,29 +30,16 @@ function getFileContents(file) { return file.contents.toString(); } -function getConfig(file) { - const contents = getFileContents(file).replace(/\r?\n/gm, ''); - return contents.split('kibana.Plugin(')[1]; -} - describe('plugin generator sao integration', () => { - test.skip('skips files when answering no', async () => { + test('skips files when answering no', async () => { const res = await sao.mockPrompt(template, { generateApp: false, generateApi: false, }); - expect(res.fileList).not.toContain('public/app.js'); - expect(res.fileList).not.toContain('public/__tests__/index.js'); - expect(res.fileList).not.toContain('public/hack.js'); - expect(res.fileList).not.toContain('server/routes/example.js'); - expect(res.fileList).not.toContain('server/__tests__/index.js'); - - const uiExports = getConfig(res.files['index.js']); - expect(uiExports).not.toContain('app:'); - expect(uiExports).not.toContain('hacks:'); - expect(uiExports).not.toContain('init(server, options)'); - expect(uiExports).not.toContain('registerFeature('); + expect(res.fileList).toContain('common/index.ts'); + expect(res.fileList).not.toContain('public/index.ts'); + expect(res.fileList).not.toContain('server/index.ts'); }); it('includes app when answering yes', async () => { @@ -69,26 +54,21 @@ describe('plugin generator sao integration', () => { expect(res.fileList).toContain('public/plugin.ts'); expect(res.fileList).toContain('public/types.ts'); expect(res.fileList).toContain('public/components/app.tsx'); + expect(res.fileList).not.toContain('server/index.ts'); }); - it.skip('includes server api when answering yes', async () => { + it('includes server api when answering yes', async () => { const res = await sao.mockPrompt(template, { generateApp: true, generateApi: true, }); // check output files - expect(res.fileList).toContain('public/app.js'); - expect(res.fileList).toContain('public/__tests__/index.js'); - expect(res.fileList).toContain('public/hack.js'); - expect(res.fileList).toContain('server/routes/example.js'); - expect(res.fileList).toContain('server/__tests__/index.js'); - - const uiExports = getConfig(res.files['index.js']); - expect(uiExports).toContain('app:'); - expect(uiExports).toContain('hacks:'); - expect(uiExports).toContain('init(server, options)'); - expect(uiExports).toContain('registerFeature('); + expect(res.fileList).toContain('public/plugin.ts'); + expect(res.fileList).toContain('server/plugin.ts'); + expect(res.fileList).toContain('server/index.ts'); + expect(res.fileList).toContain('server/types.ts'); + expect(res.fileList).toContain('server/routes/index.ts'); }); it('plugin package has correct title', async () => { @@ -125,17 +105,6 @@ describe('plugin generator sao integration', () => { expect(pkg.version).toBe('v6.0.0'); }); - it.skip('package has correct templateVersion', async () => { - const res = await sao.mockPrompt(template, { - kbnVersion: 'master', - }); - - const packageContents = getFileContents(res.files['kibana.json']); - const pkg = JSON.parse(packageContents); - - expect(pkg.kibana.templateVersion).toBe(templatePkg.version); - }); - it('sample app has correct values', async () => { const res = await sao.mockPrompt(template, { generateApp: true, @@ -148,9 +117,8 @@ describe('plugin generator sao integration', () => { expect(controllerLine).toContain('someFancyPlugin'); }); - it.skip('includes dotfiles', async () => { + it('includes dotfiles', async () => { const res = await sao.mockPrompt(template); - expect(res.files['.gitignore']).toBeTruthy(); expect(res.files['.eslintrc.js']).toBeTruthy(); }); }); From 1952d7571bb38fef3931beeffc6d8a620a9f63ff Mon Sep 17 00:00:00 2001 From: Liza K Date: Fri, 31 Jan 2020 00:50:18 +0200 Subject: [PATCH 21/23] Fix regex --- .../integration_tests/generate_plugin.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js index 7cacfcf93937b..129125c4583d5 100644 --- a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js +++ b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js @@ -101,7 +101,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug '--migrations.skip=true', ], cwd: generatedPath, - wait: /ispec_plugin.+Setting up plugin/, + wait: new RegExp('\\[ispecPlugin\\]\\[plugins\\] Setting up plugin'), }); await proc.stop('kibana'); }); From 0b9ca29b1bd2440a091877f4ef0e8f54e4eb2357 Mon Sep 17 00:00:00 2001 From: Liza K Date: Fri, 31 Jan 2020 00:53:48 +0200 Subject: [PATCH 22/23] review comments --- packages/kbn-plugin-generator/sao_template/sao.js | 2 +- .../sao_template/template/public/components/app.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index 168fb78d56e83..e6c0c8bec7af3 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -63,7 +63,7 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { }, generateEslint: { type: 'confirm', - message: 'Should generate custom eslint file be used?', + message: 'Would you like to use a custom eslint file?', default: !isKibanaPlugin, }, }, diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx index d6a79906d37b9..7b259a9c5b99d 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/app.tsx @@ -57,7 +57,7 @@ export const <%= upperCamelCaseName %>App = ({ basename, notifications, http, na http.get('/api/<%= snakeCase(name) %>/example').then(res => { setTimestamp(res.time); // Use the core notifications service to display a success message. - notifications.toasts.addSuccess(i18n.translate('banana.dataUpdated', { + notifications.toasts.addSuccess(i18n.translate('<%= camelCase(name) %>.dataUpdated', { defaultMessage: 'Data updated', })); }); From 8ad025ec6f55e8a55cd3edb61ff6f6369b4f79a9 Mon Sep 17 00:00:00 2001 From: Liza K Date: Sun, 2 Feb 2020 10:42:40 +0200 Subject: [PATCH 23/23] code review --- packages/kbn-plugin-generator/sao_template/sao.js | 14 +++++++------- .../sao_template/template/public/application.tsx | 4 ++-- .../sao_template/template/public/index.ts | 6 ++---- .../sao_template/template/public/plugin.ts | 4 ++-- .../sao_template/template/public/types.ts | 2 +- .../sao_template/template/server/index.ts | 8 ++++---- 6 files changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index e6c0c8bec7af3..aed4b9a02838f 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -50,11 +50,11 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { message: 'Should a server API be generated?', default: true, }, - generateTranslations: { - type: 'confirm', - message: 'Should translation files be generated?', - default: true, - }, + // generateTranslations: { + // type: 'confirm', + // message: 'Should translation files be generated?', + // default: true, + // }, generateScss: { type: 'confirm', message: 'Should SCSS be used?', @@ -71,8 +71,8 @@ module.exports = function({ name, targetPath, isKibanaPlugin }) { 'public/**/index.scss': 'generateScss', 'public/**/*': 'generateApp', 'server/**/*': 'generateApi', - 'translations/**/*': 'generateTranslations', - '.i18nrc.json': 'generateTranslations', + // 'translations/**/*': 'generateTranslations', + // '.i18nrc.json': 'generateTranslations', 'eslintrc.js': 'generateEslint', }, move: { diff --git a/packages/kbn-plugin-generator/sao_template/template/public/application.tsx b/packages/kbn-plugin-generator/sao_template/template/public/application.tsx index 581d414c0a578..8106a18a784e7 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/application.tsx +++ b/packages/kbn-plugin-generator/sao_template/template/public/application.tsx @@ -1,13 +1,13 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { AppMountParameters, CoreStart } from '<%= relRoot %>/src/core/public'; -import { AppPluginDependencies } from './types'; +import { AppPluginStartDependencies } from './types'; import { <%= upperCamelCaseName %>App } from './components/app'; export const renderApp = ( { notifications, http }: CoreStart, - { navigation }: AppPluginDependencies, + { navigation }: AppPluginStartDependencies, { appBasePath, element }: AppMountParameters ) => { ReactDOM.render( diff --git a/packages/kbn-plugin-generator/sao_template/template/public/index.ts b/packages/kbn-plugin-generator/sao_template/template/public/index.ts index 246b5aca73cce..2999dc7264ddb 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/index.ts @@ -4,10 +4,8 @@ import './index.scss'; import { <%= upperCamelCaseName %>Plugin } from './plugin'; -/** - * This exports static code and TypeScript types, - * as well as, Kibana Platform `plugin()` initializer. - **/ +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. export function plugin() { return new <%= upperCamelCaseName %>Plugin(); } diff --git a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts index cc46e1cf0c1d7..76f7f1a6f9908 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/plugin.ts @@ -1,6 +1,6 @@ import { i18n } from '@kbn/i18n'; import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '<%= relRoot %>/src/core/public'; -import { <%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart, AppPluginDependencies } from './types'; +import { <%= upperCamelCaseName %>PluginSetup, <%= upperCamelCaseName %>PluginStart, AppPluginStartDependencies } from './types'; import { PLUGIN_NAME } from '../common'; export class <%= upperCamelCaseName %>Plugin @@ -17,7 +17,7 @@ export class <%= upperCamelCaseName %>Plugin // Get start services as specified in kibana.json const [coreStart, depsStart] = await core.getStartServices(); // Render the application - return renderApp(coreStart, depsStart as AppPluginDependencies, params); + return renderApp(coreStart, depsStart as AppPluginStartDependencies, params); }, }); diff --git a/packages/kbn-plugin-generator/sao_template/template/public/types.ts b/packages/kbn-plugin-generator/sao_template/template/public/types.ts index 43d2c38bffd86..2ebb0c0d1257f 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/types.ts +++ b/packages/kbn-plugin-generator/sao_template/template/public/types.ts @@ -6,6 +6,6 @@ export interface <%= upperCamelCaseName %>PluginSetup { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface <%= upperCamelCaseName %>PluginStart {} -export interface AppPluginDependencies { +export interface AppPluginStartDependencies { navigation: NavigationPublicPluginStart }; diff --git a/packages/kbn-plugin-generator/sao_template/template/server/index.ts b/packages/kbn-plugin-generator/sao_template/template/server/index.ts index f34203722e0cc..816b8faec2a45 100644 --- a/packages/kbn-plugin-generator/sao_template/template/server/index.ts +++ b/packages/kbn-plugin-generator/sao_template/template/server/index.ts @@ -1,10 +1,10 @@ import { PluginInitializerContext } from '<%= relRoot %>/src/core/server'; import { <%= upperCamelCaseName %>Plugin } from './plugin'; -/** - * This exports static code and TypeScript types, - * as well as, Kibana Platform `plugin()` initializer. - **/ + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. + export function plugin(initializerContext: PluginInitializerContext) { return new <%= upperCamelCaseName %>Plugin(initializerContext); }