From f089c7ee5e5bb768f8148f95fafe792b5fbcb3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 20 Dec 2018 09:25:04 +0100 Subject: [PATCH 01/13] Grafana ui library poc --- package.json | 4 +++- packages/grafana-ui/index.ts | 21 +++++++++++++++++++ packages/grafana-ui/package.json | 11 ++++++++++ .../dashboard/dashgrid/DashboardGrid.tsx | 3 +++ public/app/features/plugins/plugin_loader.ts | 2 ++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 packages/grafana-ui/index.ts create mode 100644 packages/grafana-ui/package.json diff --git a/package.json b/package.json index d374cd524b4..31e80e3b47d 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "private": true, "author": { "name": "Torkel Ödegaard", "company": "Grafana Labs" @@ -178,5 +179,6 @@ "resolutions": { "caniuse-db": "1.0.30000772", "**/@types/react": "16.7.6" - } + }, + "workspaces": ["packages/grafana-ui"] } diff --git a/packages/grafana-ui/index.ts b/packages/grafana-ui/index.ts new file mode 100644 index 00000000000..4beb45d6fb3 --- /dev/null +++ b/packages/grafana-ui/index.ts @@ -0,0 +1,21 @@ +export class Google { + hello() { + return 'hello'; + } +} + +class Singleton { + constructor(private state) {} + + hello() { + return this.state; + } + + change() { + this.state = 'mod2'; + } +} + +const singletonSrv = new Singleton('hello'); + +export { singletonSrv }; diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json new file mode 100644 index 00000000000..e3c407b500a --- /dev/null +++ b/packages/grafana-ui/package.json @@ -0,0 +1,11 @@ +{ + "name": "grafana-ui", + "version": "1.0.0", + "description": "", + "main": "index.ts", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index a401505b787..ad15eca8654 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -7,6 +7,9 @@ import { DashboardModel } from '../dashboard_model'; import { PanelModel } from '../panel_model'; import classNames from 'classnames'; import sizeMe from 'react-sizeme'; +import { Google } from 'grafana-ui'; + +console.log(Google); let lastGridWidth = 1200; let ignoreNextWidthChange = false; diff --git a/public/app/features/plugins/plugin_loader.ts b/public/app/features/plugins/plugin_loader.ts index 8e0958f6c1b..97e35ab5631 100644 --- a/public/app/features/plugins/plugin_loader.ts +++ b/public/app/features/plugins/plugin_loader.ts @@ -26,6 +26,7 @@ import * as ticks from 'app/core/utils/ticks'; import impressionSrv from 'app/core/services/impression_srv'; import builtInPlugins from './built_in_plugins'; import * as d3 from 'd3'; +import * as grafanaUI from 'grafana-ui'; // rxjs import { Observable } from 'rxjs/Observable'; @@ -71,6 +72,7 @@ function exposeToPlugin(name: string, component: any) { }); } +exposeToPlugin('grafana-ui', grafanaUI); exposeToPlugin('lodash', _); exposeToPlugin('moment', moment); exposeToPlugin('jquery', jquery); From 6e66b2b90646e8c63fef0d697a7b833ea6c4fb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 20 Dec 2018 16:56:46 +0100 Subject: [PATCH 02/13] breaking up grafana into multiple packages poc --- packages/grafana-ui/package.json | 12 ++++--- packages/grafana-ui/{ => src}/index.ts | 7 +++- packages/grafana-ui/src/other.ts | 5 +++ packages/grafana-ui/tsconfig.json | 36 +++++++++++++++++++ packages/grafana-ui/types/index.ts | 4 +++ .../dashboard/dashgrid/VisualizationTab.tsx | 1 + public/app/features/plugins/plugin_loader.ts | 2 +- yarn.lock | 5 +++ 8 files changed, 66 insertions(+), 6 deletions(-) rename packages/grafana-ui/{ => src}/index.ts (63%) create mode 100644 packages/grafana-ui/src/other.ts create mode 100644 packages/grafana-ui/tsconfig.json create mode 100644 packages/grafana-ui/types/index.ts diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index e3c407b500a..73eff40d3d7 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -1,11 +1,15 @@ { - "name": "grafana-ui", + "name": "@grafana/ui", "version": "1.0.0", "description": "", - "main": "index.ts", + "main": "dist/index.js", + "types": "dist/types", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "tsc --noEmit" }, "author": "", - "license": "ISC" + "license": "ISC", + "devDependencies": { + "typescript": "^3.2.2" + } } diff --git a/packages/grafana-ui/index.ts b/packages/grafana-ui/src/index.ts similarity index 63% rename from packages/grafana-ui/index.ts rename to packages/grafana-ui/src/index.ts index 4beb45d6fb3..015fff3bca8 100644 --- a/packages/grafana-ui/index.ts +++ b/packages/grafana-ui/src/index.ts @@ -1,11 +1,16 @@ +export { Other } from './other'; +import { TimeSeries } from '../types'; + export class Google { + data: TimeSeries; + hello() { return 'hello'; } } class Singleton { - constructor(private state) {} + constructor(private state: string) {} hello() { return this.state; diff --git a/packages/grafana-ui/src/other.ts b/packages/grafana-ui/src/other.ts new file mode 100644 index 00000000000..cbc1390dd05 --- /dev/null +++ b/packages/grafana-ui/src/other.ts @@ -0,0 +1,5 @@ +export class Other { + static hello() { + return "hello from other"; + } +} diff --git a/packages/grafana-ui/tsconfig.json b/packages/grafana-ui/tsconfig.json new file mode 100644 index 00000000000..f9e577c23d0 --- /dev/null +++ b/packages/grafana-ui/tsconfig.json @@ -0,0 +1,36 @@ +{ + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "exclude": [ + "dist" + ], + "scripts": { + "build": "tsc" + }, + "compilerOptions": { + "moduleResolution": "node", + "target": "es5", + "lib": ["es6", "dom"], + "jsx": "react", + "module": "esnext", + "outDir": "dist", + "declaration": false, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "importHelpers": true, + "noEmitHelpers": true, + "removeComments": false, + "inlineSourceMap": false, + "sourceMap": true, + "noEmitOnError": false, + "emitDecoratorMetadata": false, + "experimentalDecorators": true, + "declaration": true, + "declarationDir": "./dist/types", + "noImplicitAny": true, + "strictNullChecks": true + } +} diff --git a/packages/grafana-ui/types/index.ts b/packages/grafana-ui/types/index.ts new file mode 100644 index 00000000000..ed86915b4cf --- /dev/null +++ b/packages/grafana-ui/types/index.ts @@ -0,0 +1,4 @@ + +export interface TimeSeries { + name: string; +} diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 42d9bf6a6eb..53364502383 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -15,6 +15,7 @@ import { PanelOptionSection } from './PanelOptionSection'; import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; import { PanelPlugin } from 'app/types/plugins'; +import { TimeSeries } from '@grafana/ui/types'; interface Props { panel: PanelModel; diff --git a/public/app/features/plugins/plugin_loader.ts b/public/app/features/plugins/plugin_loader.ts index 97e35ab5631..2c394cb77e7 100644 --- a/public/app/features/plugins/plugin_loader.ts +++ b/public/app/features/plugins/plugin_loader.ts @@ -26,7 +26,7 @@ import * as ticks from 'app/core/utils/ticks'; import impressionSrv from 'app/core/services/impression_srv'; import builtInPlugins from './built_in_plugins'; import * as d3 from 'd3'; -import * as grafanaUI from 'grafana-ui'; +import * as grafanaUI from '@grafana/ui'; // rxjs import { Observable } from 'rxjs/Observable'; diff --git a/yarn.lock b/yarn.lock index 9bc6c7dcd63..ecdc347c4f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14544,6 +14544,11 @@ typescript@^3.0.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.1.tgz#3362ba9dd1e482ebb2355b02dfe8bcd19a2c7c96" integrity sha512-Veu0w4dTc/9wlWNf2jeRInNodKlcdLgemvPsrNpfu5Pq39sgfFjvIIgTsvUHCoLBnMhPoUA+tFxsXjU6VexVRQ== +typescript@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5" + integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg== + ua-parser-js@^0.7.18: version "0.7.19" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b" From 2fec5c7577caa09e83333861763992c00fb2d078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 21 Dec 2018 12:27:43 +0100 Subject: [PATCH 03/13] Grafana ui lib is starting to work --- packages/grafana-ui/package.json | 3 +-- .../DeleteButton/DeleteButton.test.tsx | 0 .../components/DeleteButton/DeleteButton.tsx | 14 +++++----- packages/grafana-ui/src/components/index.ts | 1 + packages/grafana-ui/src/index.ts | 27 +------------------ packages/grafana-ui/src/other.ts | 5 ---- packages/grafana-ui/types/index.ts | 4 --- public/app/features/api-keys/ApiKeysPage.tsx | 4 +-- .../dashboard/dashgrid/DashboardGrid.tsx | 3 --- .../dashboard/dashgrid/VisualizationTab.tsx | 1 - public/app/features/plugins/plugin_loader.ts | 2 +- public/app/features/teams/TeamList.tsx | 4 +-- public/app/features/teams/TeamMembers.tsx | 4 +-- 13 files changed, 17 insertions(+), 55 deletions(-) rename {public/app/core => packages/grafana-ui/src}/components/DeleteButton/DeleteButton.test.tsx (100%) rename {public/app/core => packages/grafana-ui/src}/components/DeleteButton/DeleteButton.tsx (81%) create mode 100644 packages/grafana-ui/src/components/index.ts delete mode 100644 packages/grafana-ui/src/other.ts delete mode 100644 packages/grafana-ui/types/index.ts diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 73eff40d3d7..1466e0de80a 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -2,8 +2,7 @@ "name": "@grafana/ui", "version": "1.0.0", "description": "", - "main": "dist/index.js", - "types": "dist/types", + "main": "src/index.ts", "scripts": { "test": "tsc --noEmit" }, diff --git a/public/app/core/components/DeleteButton/DeleteButton.test.tsx b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.test.tsx similarity index 100% rename from public/app/core/components/DeleteButton/DeleteButton.test.tsx rename to packages/grafana-ui/src/components/DeleteButton/DeleteButton.test.tsx diff --git a/public/app/core/components/DeleteButton/DeleteButton.tsx b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx similarity index 81% rename from public/app/core/components/DeleteButton/DeleteButton.tsx rename to packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx index a83ce6097ad..de2db07aa04 100644 --- a/public/app/core/components/DeleteButton/DeleteButton.tsx +++ b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx @@ -1,15 +1,15 @@ import React, { PureComponent } from 'react'; -export interface DeleteButtonProps { - onConfirmDelete(); +interface Props { + onConfirm(); } -export interface DeleteButtonStates { +interface State { showConfirm: boolean; } -export default class DeleteButton extends PureComponent { - state: DeleteButtonStates = { +export class DeleteButton extends PureComponent { + state: State = { showConfirm: false, }; @@ -33,7 +33,7 @@ export default class DeleteButton extends PureComponent Cancel - + Confirm Delete diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts new file mode 100644 index 00000000000..b57b9bcfdb7 --- /dev/null +++ b/packages/grafana-ui/src/components/index.ts @@ -0,0 +1 @@ +export { DeleteButton } from './DeleteButton/DeleteButton'; diff --git a/packages/grafana-ui/src/index.ts b/packages/grafana-ui/src/index.ts index 015fff3bca8..07635cbbc8e 100644 --- a/packages/grafana-ui/src/index.ts +++ b/packages/grafana-ui/src/index.ts @@ -1,26 +1 @@ -export { Other } from './other'; -import { TimeSeries } from '../types'; - -export class Google { - data: TimeSeries; - - hello() { - return 'hello'; - } -} - -class Singleton { - constructor(private state: string) {} - - hello() { - return this.state; - } - - change() { - this.state = 'mod2'; - } -} - -const singletonSrv = new Singleton('hello'); - -export { singletonSrv }; +export * from './components'; diff --git a/packages/grafana-ui/src/other.ts b/packages/grafana-ui/src/other.ts deleted file mode 100644 index cbc1390dd05..00000000000 --- a/packages/grafana-ui/src/other.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class Other { - static hello() { - return "hello from other"; - } -} diff --git a/packages/grafana-ui/types/index.ts b/packages/grafana-ui/types/index.ts deleted file mode 100644 index ed86915b4cf..00000000000 --- a/packages/grafana-ui/types/index.ts +++ /dev/null @@ -1,4 +0,0 @@ - -export interface TimeSeries { - name: string; -} diff --git a/public/app/features/api-keys/ApiKeysPage.tsx b/public/app/features/api-keys/ApiKeysPage.tsx index d2aa1f24c57..e14873fa9f6 100644 --- a/public/app/features/api-keys/ApiKeysPage.tsx +++ b/public/app/features/api-keys/ApiKeysPage.tsx @@ -13,7 +13,7 @@ import ApiKeysAddedModal from './ApiKeysAddedModal'; import config from 'app/core/config'; import appEvents from 'app/core/app_events'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import DeleteButton from 'app/core/components/DeleteButton/DeleteButton'; +import { DeleteButton } from '@grafana/ui'; export interface Props { navModel: NavModel; @@ -224,7 +224,7 @@ export class ApiKeysPage extends PureComponent { {key.name} {key.role} - this.onDeleteApiKey(key)} /> + this.onDeleteApiKey(key)} /> ); diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index ad15eca8654..a401505b787 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -7,9 +7,6 @@ import { DashboardModel } from '../dashboard_model'; import { PanelModel } from '../panel_model'; import classNames from 'classnames'; import sizeMe from 'react-sizeme'; -import { Google } from 'grafana-ui'; - -console.log(Google); let lastGridWidth = 1200; let ignoreNextWidthChange = false; diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 53364502383..42d9bf6a6eb 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -15,7 +15,6 @@ import { PanelOptionSection } from './PanelOptionSection'; import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; import { PanelPlugin } from 'app/types/plugins'; -import { TimeSeries } from '@grafana/ui/types'; interface Props { panel: PanelModel; diff --git a/public/app/features/plugins/plugin_loader.ts b/public/app/features/plugins/plugin_loader.ts index 2c394cb77e7..775cf9507fe 100644 --- a/public/app/features/plugins/plugin_loader.ts +++ b/public/app/features/plugins/plugin_loader.ts @@ -72,7 +72,7 @@ function exposeToPlugin(name: string, component: any) { }); } -exposeToPlugin('grafana-ui', grafanaUI); +exposeToPlugin('@grafana/ui', grafanaUI); exposeToPlugin('lodash', _); exposeToPlugin('moment', moment); exposeToPlugin('jquery', jquery); diff --git a/public/app/features/teams/TeamList.tsx b/public/app/features/teams/TeamList.tsx index d8e12e338e9..d1551d6baa6 100644 --- a/public/app/features/teams/TeamList.tsx +++ b/public/app/features/teams/TeamList.tsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; import { hot } from 'react-hot-loader'; import PageHeader from 'app/core/components/PageHeader/PageHeader'; -import DeleteButton from 'app/core/components/DeleteButton/DeleteButton'; +import { DeleteButton } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import PageLoader from 'app/core/components/PageLoader/PageLoader'; import { NavModel, Team } from '../../types'; @@ -58,7 +58,7 @@ export class TeamList extends PureComponent { {team.memberCount} - this.deleteTeam(team)} /> + this.deleteTeam(team)} /> ); diff --git a/public/app/features/teams/TeamMembers.tsx b/public/app/features/teams/TeamMembers.tsx index 0e20f4be664..a25f1786a5b 100644 --- a/public/app/features/teams/TeamMembers.tsx +++ b/public/app/features/teams/TeamMembers.tsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; import SlideDown from 'app/core/components/Animations/SlideDown'; import { UserPicker } from 'app/core/components/Select/UserPicker'; -import DeleteButton from 'app/core/components/DeleteButton/DeleteButton'; +import { DeleteButton } from '@grafana/ui'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; import { TeamMember, User } from 'app/types'; import { loadTeamMembers, addTeamMember, removeTeamMember, setSearchMemberQuery } from './state/actions'; @@ -76,7 +76,7 @@ export class TeamMembers extends PureComponent { {member.email} {syncEnabled && this.renderLabels(member.labels)} - this.onRemoveMember(member)} /> + this.onRemoveMember(member)} /> ); From 52f583fee762e35a88040d152e5a6a9cfe5ad05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 21 Dec 2018 14:23:32 +0100 Subject: [PATCH 04/13] @grafana/ui lib now contains one components, seperate lint & tsc steps --- jest.config.js | 4 +++- package.json | 3 ++- packages/grafana-ui/package.json | 14 +++++++++++- .../DeleteButton/DeleteButton.test.tsx | 9 ++++---- .../components/DeleteButton/DeleteButton.tsx | 8 +++---- packages/grafana-ui/tsconfig.json | 22 ++----------------- packages/grafana-ui/tslint.json | 3 +++ .../__snapshots__/TeamList.test.tsx.snap | 10 ++++----- .../__snapshots__/TeamMembers.test.tsx.snap | 20 ++++++++--------- scripts/grunt/default_task.js | 16 +++++++++++--- scripts/grunt/options/exec.js | 16 ++++++++++---- scripts/grunt/options/sasslint.js | 1 + scripts/grunt/options/tslint.js | 11 ---------- 13 files changed, 73 insertions(+), 64 deletions(-) create mode 100644 packages/grafana-ui/tslint.json delete mode 100644 scripts/grunt/options/tslint.js diff --git a/jest.config.js b/jest.config.js index cac634fbf10..e4d669edd8f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,7 +6,9 @@ module.exports = { }, "moduleDirectories": ["node_modules", "public"], "roots": [ - "/public" + "/public/app", + "/public/test", + "packages" ], "testRegex": "(\\.|/)(test)\\.(jsx?|tsx?)$", "moduleFileExtensions": [ diff --git a/package.json b/package.json index 31e80e3b47d..0f0f7fefa83 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,8 @@ "watch": "webpack --progress --colors --watch --mode development --config scripts/webpack/webpack.dev.js", "build": "grunt build", "test": "grunt test", - "lint": "tslint -c tslint.json --project tsconfig.json", + "tslint": "tslint -c tslint.json --project tsconfig.json", + "typecheck": "tsc --noEmit", "jest": "jest --notify --watch", "api-tests": "jest --notify --watch --config=tests/api/jest.js", "precommit": "lint-staged && grunt precommit" diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 1466e0de80a..39950d31d71 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -4,11 +4,23 @@ "description": "", "main": "src/index.ts", "scripts": { - "test": "tsc --noEmit" + "tslint": "tslint -c tslint.json --project tsconfig.json", + "typecheck": "tsc --noEmit" }, "author": "", "license": "ISC", + "dependencies": { + "react": "^16.6.3", + "react-dom": "^16.6.3", + "react-popper": "^1.3.0", + "react-highlight-words": "0.11.0", + "@torkelo/react-select": "2.1.1", + "react-transition-group": "^2.2.1", + "react-virtualized": "^9.21.0" + }, "devDependencies": { + "@types/jest": "^23.3.2", + "@types/react": "^16.7.6", "typescript": "^3.2.2" } } diff --git a/packages/grafana-ui/src/components/DeleteButton/DeleteButton.test.tsx b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.test.tsx index 12acadee18a..f6d5a676971 100644 --- a/packages/grafana-ui/src/components/DeleteButton/DeleteButton.test.tsx +++ b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.test.tsx @@ -1,10 +1,10 @@ import React from 'react'; -import DeleteButton from './DeleteButton'; +import { DeleteButton } from './DeleteButton'; import { shallow } from 'enzyme'; describe('DeleteButton', () => { - let wrapper; - let deleted; + let wrapper: any; + let deleted: any; beforeAll(() => { deleted = false; @@ -12,7 +12,8 @@ describe('DeleteButton', () => { function deleteItem() { deleted = true; } - wrapper = shallow( deleteItem()} />); + + wrapper = shallow( deleteItem()} />); }); it('should show confirm delete when clicked', () => { diff --git a/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx index de2db07aa04..df65d156ab3 100644 --- a/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx +++ b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx @@ -1,7 +1,7 @@ -import React, { PureComponent } from 'react'; +import React, { PureComponent, SyntheticEvent } from 'react'; interface Props { - onConfirm(); + onConfirm(): void; } interface State { @@ -13,7 +13,7 @@ export class DeleteButton extends PureComponent { showConfirm: false, }; - onClickDelete = event => { + onClickDelete = (event: SyntheticEvent) => { if (event) { event.preventDefault(); } @@ -23,7 +23,7 @@ export class DeleteButton extends PureComponent { }); }; - onClickCancel = event => { + onClickCancel = (event: SyntheticEvent) => { if (event) { event.preventDefault(); } diff --git a/packages/grafana-ui/tsconfig.json b/packages/grafana-ui/tsconfig.json index f9e577c23d0..ed6009f1ebd 100644 --- a/packages/grafana-ui/tsconfig.json +++ b/packages/grafana-ui/tsconfig.json @@ -1,4 +1,5 @@ { + "extends": "../../tsconfig.json", "include": [ "src/**/*.ts", "src/**/*.tsx" @@ -6,30 +7,11 @@ "exclude": [ "dist" ], - "scripts": { - "build": "tsc" - }, "compilerOptions": { - "moduleResolution": "node", - "target": "es5", - "lib": ["es6", "dom"], - "jsx": "react", + "rootDir": ".", "module": "esnext", "outDir": "dist", - "declaration": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "importHelpers": true, - "noEmitHelpers": true, - "removeComments": false, - "inlineSourceMap": false, - "sourceMap": true, - "noEmitOnError": false, - "emitDecoratorMetadata": false, - "experimentalDecorators": true, "declaration": true, - "declarationDir": "./dist/types", "noImplicitAny": true, "strictNullChecks": true } diff --git a/packages/grafana-ui/tslint.json b/packages/grafana-ui/tslint.json new file mode 100644 index 00000000000..0946f20963a --- /dev/null +++ b/packages/grafana-ui/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tslint.json" +} diff --git a/public/app/features/teams/__snapshots__/TeamList.test.tsx.snap b/public/app/features/teams/__snapshots__/TeamList.test.tsx.snap index 73f081d496a..ae94691df0e 100644 --- a/public/app/features/teams/__snapshots__/TeamList.test.tsx.snap +++ b/public/app/features/teams/__snapshots__/TeamList.test.tsx.snap @@ -124,7 +124,7 @@ exports[`Render should render teams table 1`] = ` className="text-right" > @@ -174,7 +174,7 @@ exports[`Render should render teams table 1`] = ` className="text-right" > @@ -224,7 +224,7 @@ exports[`Render should render teams table 1`] = ` className="text-right" > @@ -274,7 +274,7 @@ exports[`Render should render teams table 1`] = ` className="text-right" > @@ -324,7 +324,7 @@ exports[`Render should render teams table 1`] = ` className="text-right" > diff --git a/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap b/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap index d0a88bd97b0..5ebddb36d48 100644 --- a/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap +++ b/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap @@ -204,7 +204,7 @@ exports[`Render should render team members 1`] = ` className="text-right" > @@ -229,7 +229,7 @@ exports[`Render should render team members 1`] = ` className="text-right" > @@ -254,7 +254,7 @@ exports[`Render should render team members 1`] = ` className="text-right" > @@ -279,7 +279,7 @@ exports[`Render should render team members 1`] = ` className="text-right" > @@ -304,7 +304,7 @@ exports[`Render should render team members 1`] = ` className="text-right" > @@ -441,7 +441,7 @@ exports[`Render should render team members when sync enabled 1`] = ` className="text-right" > @@ -482,7 +482,7 @@ exports[`Render should render team members when sync enabled 1`] = ` className="text-right" > @@ -523,7 +523,7 @@ exports[`Render should render team members when sync enabled 1`] = ` className="text-right" > @@ -564,7 +564,7 @@ exports[`Render should render team members when sync enabled 1`] = ` className="text-right" > @@ -605,7 +605,7 @@ exports[`Render should render team members when sync enabled 1`] = ` className="text-right" > diff --git a/scripts/grunt/default_task.js b/scripts/grunt/default_task.js index 7b975aac977..1deb23eb220 100644 --- a/scripts/grunt/default_task.js +++ b/scripts/grunt/default_task.js @@ -15,10 +15,20 @@ module.exports = function (grunt) { 'no-only-tests' ]); + grunt.registerTask('tslint', [ + 'newer:exec:tslintPackages', + 'newer:exec:tslintRoot', + ]); + + grunt.registerTask('typecheck', [ + 'newer:exec:typecheckPackages', + 'newer:exec:typecheckRoot', + ]); + grunt.registerTask('precommit', [ - 'sasslint', - 'newer:exec:tslint', - 'newer:exec:tsc', + 'newer:sasslint', + 'typecheck', + 'tslint', 'no-only-tests' ]); diff --git a/scripts/grunt/options/exec.js b/scripts/grunt/options/exec.js index 3b60c5c3be6..27bfd7ae43d 100644 --- a/scripts/grunt/options/exec.js +++ b/scripts/grunt/options/exec.js @@ -2,12 +2,20 @@ module.exports = function (config, grunt) { 'use strict'; return { - tslint: { - command: 'node ./node_modules/tslint/lib/tslintCli.js -c tslint.json --project ./tsconfig.json', + tslintPackages: { + command: 'yarn workspaces run tslint', + src: ['packages/**/*.ts*'], + }, + tslintRoot: { + command: 'yarn run tslint', src: ['public/app/**/*.ts*'], }, - tsc: { - command: 'yarn tsc --noEmit', + typecheckPackages: { + command: 'yarn workspaces run typecheck', + src: ['packages/**/*.ts*'], + }, + typecheckRoot: { + command: 'yarn run typecheck', src: ['public/app/**/*.ts*'], }, jest: 'node ./node_modules/jest-cli/bin/jest.js --maxWorkers 2', diff --git a/scripts/grunt/options/sasslint.js b/scripts/grunt/options/sasslint.js index 8ba5ea3047f..9877f49a5a3 100644 --- a/scripts/grunt/options/sasslint.js +++ b/scripts/grunt/options/sasslint.js @@ -4,6 +4,7 @@ module.exports = function(config) { options: { configFile: 'public/sass/.sass-lint.yml', }, + // src: ['public/sass#<{(||)}>#*'], target: [ 'public/sass/*.scss', 'public/sass/components/*.scss', diff --git a/scripts/grunt/options/tslint.js b/scripts/grunt/options/tslint.js deleted file mode 100644 index d51c2062676..00000000000 --- a/scripts/grunt/options/tslint.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = function(config, grunt) { - 'use strict' - // dummy to avoid template compile error - return { - source: { - files: { - src: "" - } - } - }; -}; From 7268f16c54ea4fec7e6434cd991f524b648a171d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 21 Dec 2018 14:37:38 +0100 Subject: [PATCH 05/13] grunt test task update --- scripts/grunt/default_task.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/grunt/default_task.js b/scripts/grunt/default_task.js index 1deb23eb220..8a71ea26627 100644 --- a/scripts/grunt/default_task.js +++ b/scripts/grunt/default_task.js @@ -10,7 +10,8 @@ module.exports = function (grunt) { grunt.registerTask('test', [ 'sasslint', - 'exec:tslint', + 'tslint', + 'typecheck', "exec:jest", 'no-only-tests' ]); From 0ff572efbf539ac46cc616a6089b426907292057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sun, 23 Dec 2018 08:26:07 +0100 Subject: [PATCH 06/13] Testing moving out one type to grafana/ui --- jest.config.js | 2 +- packages/grafana-ui/package.json | 1 + packages/grafana-ui/src/index.ts | 1 + packages/grafana-ui/src/types/index.ts | 1 + packages/grafana-ui/src/types/series.ts | 13 +++++++++++++ .../app/features/dashboard/dashgrid/DataPanel.tsx | 3 ++- public/app/types/index.ts | 2 -- public/app/types/panel.ts | 3 ++- public/app/types/series.ts | 7 ------- 9 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 packages/grafana-ui/src/types/index.ts create mode 100644 packages/grafana-ui/src/types/series.ts diff --git a/jest.config.js b/jest.config.js index e4d669edd8f..c5c6bcb9f5f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -8,7 +8,7 @@ module.exports = { "roots": [ "/public/app", "/public/test", - "packages" + "/packages" ], "testRegex": "(\\.|/)(test)\\.(jsx?|tsx?)$", "moduleFileExtensions": [ diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 39950d31d71..0c023817b9f 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -16,6 +16,7 @@ "react-highlight-words": "0.11.0", "@torkelo/react-select": "2.1.1", "react-transition-group": "^2.2.1", + "moment": "^2.22.2", "react-virtualized": "^9.21.0" }, "devDependencies": { diff --git a/packages/grafana-ui/src/index.ts b/packages/grafana-ui/src/index.ts index 07635cbbc8e..195d95f598d 100644 --- a/packages/grafana-ui/src/index.ts +++ b/packages/grafana-ui/src/index.ts @@ -1 +1,2 @@ export * from './components'; +export * from './types'; diff --git a/packages/grafana-ui/src/types/index.ts b/packages/grafana-ui/src/types/index.ts new file mode 100644 index 00000000000..0ca60a90923 --- /dev/null +++ b/packages/grafana-ui/src/types/index.ts @@ -0,0 +1 @@ +export * from './series'; diff --git a/packages/grafana-ui/src/types/series.ts b/packages/grafana-ui/src/types/series.ts new file mode 100644 index 00000000000..9c79ebdc99f --- /dev/null +++ b/packages/grafana-ui/src/types/series.ts @@ -0,0 +1,13 @@ +import { Moment } from 'moment'; + +export enum LoadingState { + NotStarted = 'NotStarted', + Loading = 'Loading', + Done = 'Done', + Error = 'Error', +} + +export interface RawTimeRange { + from: Moment | string; + to: Moment | string; +} diff --git a/public/app/features/dashboard/dashgrid/DataPanel.tsx b/public/app/features/dashboard/dashgrid/DataPanel.tsx index 9926410f40d..2a72b16d60f 100644 --- a/public/app/features/dashboard/dashgrid/DataPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DataPanel.tsx @@ -8,7 +8,8 @@ import { getDatasourceSrv, DatasourceSrv } from 'app/features/plugins/datasource import kbn from 'app/core/utils/kbn'; // Types -import { TimeRange, LoadingState, DataQueryOptions, DataQueryResponse, TimeSeries } from 'app/types'; +import { TimeRange, DataQueryOptions, DataQueryResponse, TimeSeries } from 'app/types'; +import { LoadingState } from '@grafana/ui'; interface RenderProps { loading: LoadingState; diff --git a/public/app/types/index.ts b/public/app/types/index.ts index f2a5f807645..dd84f4acf7d 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -10,7 +10,6 @@ import { Invitee, OrgUser, User, UsersState, UserState } from './user'; import { DataSource, DataSourceSelectItem, DataSourcesState } from './datasources'; import { TimeRange, - LoadingState, TimeSeries, TimeSeriesVM, TimeSeriesVMs, @@ -69,7 +68,6 @@ export { User, UsersState, TimeRange, - LoadingState, PanelPlugin, PanelProps, PanelOptionsProps, diff --git a/public/app/types/panel.ts b/public/app/types/panel.ts index af371e16573..d5db8256670 100644 --- a/public/app/types/panel.ts +++ b/public/app/types/panel.ts @@ -1,4 +1,5 @@ -import { LoadingState, TimeSeries, TimeRange } from './series'; +import { TimeSeries, TimeRange } from './series'; +import { LoadingState } from '@grafana/ui'; export interface PanelProps { timeSeries: TimeSeries[]; diff --git a/public/app/types/series.ts b/public/app/types/series.ts index a9585a2c842..f7e196a03f5 100644 --- a/public/app/types/series.ts +++ b/public/app/types/series.ts @@ -1,13 +1,6 @@ import { Moment } from 'moment'; import { PluginMeta } from './plugins'; -export enum LoadingState { - NotStarted = 'NotStarted', - Loading = 'Loading', - Done = 'Done', - Error = 'Error', -} - export interface RawTimeRange { from: Moment | string; to: Moment | string; From a02b4b47b61d737bc323600788556746dfe8a65c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sun, 23 Dec 2018 09:15:32 +0100 Subject: [PATCH 07/13] Moving a couple of types to @grafana/ui --- packages/grafana-ui/src/types/index.ts | 2 + packages/grafana-ui/src/types/panel.ts | 31 +++++++++ packages/grafana-ui/src/types/series.ts | 50 ++++++++++++-- packages/grafana-ui/src/types/time.ts | 17 +++++ public/app/core/utils/explore.ts | 3 +- public/app/core/utils/rangeutil.ts | 2 +- .../features/dashboard/dashgrid/DataPanel.tsx | 4 +- .../dashboard/dashgrid/PanelChrome.tsx | 3 +- .../dashgrid/PanelHeader/PanelHeaderMenu.tsx | 2 +- .../PanelHeader/PanelHeaderMenuItem.tsx | 2 +- .../dashgrid/PanelPluginNotFound.tsx | 6 +- public/app/features/dashboard/time_srv.ts | 4 +- .../features/dashboard/utils/getPanelMenu.ts | 2 +- public/app/features/dashboard/utils/panel.ts | 2 +- public/app/features/explore/Explore.tsx | 3 +- public/app/features/explore/Graph.tsx | 2 +- public/app/features/explore/Logs.tsx | 2 +- public/app/features/explore/QueryEditor.tsx | 2 +- public/app/features/explore/QueryRows.tsx | 2 +- public/app/features/explore/TimePicker.tsx | 2 +- .../plugins/panel/gauge/Threshold.test.tsx | 3 +- public/app/plugins/panel/gauge/module.tsx | 11 +--- .../app/plugins/panel/graph2/GraphOptions.tsx | 2 +- .../app/plugins/panel/graph2/GraphPanel.tsx | 2 +- public/app/plugins/panel/text2/module.tsx | 2 +- public/app/types/explore.ts | 3 +- public/app/types/index.ts | 24 +------ public/app/types/panel.ts | 32 --------- public/app/types/plugins.ts | 2 +- public/app/types/series.ts | 65 +------------------ public/app/viz/Gauge.tsx | 3 +- public/app/viz/Graph.tsx | 2 +- public/app/viz/state/timeSeries.ts | 2 +- 33 files changed, 137 insertions(+), 159 deletions(-) create mode 100644 packages/grafana-ui/src/types/panel.ts create mode 100644 packages/grafana-ui/src/types/time.ts diff --git a/packages/grafana-ui/src/types/index.ts b/packages/grafana-ui/src/types/index.ts index 0ca60a90923..f618ce6db34 100644 --- a/packages/grafana-ui/src/types/index.ts +++ b/packages/grafana-ui/src/types/index.ts @@ -1 +1,3 @@ export * from './series'; +export * from './time'; +export * from './panel'; diff --git a/packages/grafana-ui/src/types/panel.ts b/packages/grafana-ui/src/types/panel.ts new file mode 100644 index 00000000000..44336555a81 --- /dev/null +++ b/packages/grafana-ui/src/types/panel.ts @@ -0,0 +1,31 @@ +import { TimeSeries, LoadingState } from './series'; +import { TimeRange } from './time'; + +export interface PanelProps { + timeSeries: TimeSeries[]; + timeRange: TimeRange; + loading: LoadingState; + options: T; + renderCounter: number; + width: number; + height: number; +} + +export interface PanelOptionsProps { + options: T; + onChange: (options: T) => void; +} + +export interface PanelSize { + width: number; + height: number; +} + +export interface PanelMenuItem { + type?: 'submenu' | 'divider'; + text?: string; + iconClassName?: string; + onClick?: () => void; + shortcut?: string; + subMenu?: PanelMenuItem[]; +} diff --git a/packages/grafana-ui/src/types/series.ts b/packages/grafana-ui/src/types/series.ts index 9c79ebdc99f..6868ff567c9 100644 --- a/packages/grafana-ui/src/types/series.ts +++ b/packages/grafana-ui/src/types/series.ts @@ -1,5 +1,3 @@ -import { Moment } from 'moment'; - export enum LoadingState { NotStarted = 'NotStarted', Loading = 'Loading', @@ -7,7 +5,49 @@ export enum LoadingState { Error = 'Error', } -export interface RawTimeRange { - from: Moment | string; - to: Moment | string; +export type TimeSeriesValue = string | number | null; + +export type TimeSeriesPoints = TimeSeriesValue[][]; + +export interface TimeSeries { + target: string; + datapoints: TimeSeriesPoints; + unit?: string; +} + +/** View model projection of a time series */ +export interface TimeSeriesVM { + label: string; + color: string; + data: TimeSeriesValue[][]; + stats: TimeSeriesStats; +} + +export interface TimeSeriesStats { + total: number; + max: number; + min: number; + logmin: number; + avg: number | null; + current: number | null; + first: number | null; + delta: number; + diff: number | null; + range: number | null; + timeStep: number; + count: number; + allIsNull: boolean; + allIsZero: boolean; +} + +export enum NullValueMode { + Null = 'null', + Ignore = 'connected', + AsZero = 'null as zero', +} + +/** View model projection of many time series */ +export interface TimeSeriesVMs { + [index: number]: TimeSeriesVM; + length: number; } diff --git a/packages/grafana-ui/src/types/time.ts b/packages/grafana-ui/src/types/time.ts new file mode 100644 index 00000000000..b6acf7f07b6 --- /dev/null +++ b/packages/grafana-ui/src/types/time.ts @@ -0,0 +1,17 @@ +import { Moment } from 'moment'; + +export interface RawTimeRange { + from: Moment | string; + to: Moment | string; +} + +export interface TimeRange { + from: Moment; + to: Moment; + raw: RawTimeRange; +} + +export interface IntervalValues { + interval: string; // 10s,5m + intervalMs: number; +} diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts index f978ec1ef8c..b7de48ac479 100644 --- a/public/app/core/utils/explore.ts +++ b/public/app/core/utils/explore.ts @@ -9,7 +9,8 @@ import { parse as parseDate } from 'app/core/utils/datemath'; import TimeSeries from 'app/core/time_series2'; import TableModel, { mergeTablesIntoModel } from 'app/core/table_model'; import { ExploreState, ExploreUrlState, HistoryItem, QueryTransaction } from 'app/types/explore'; -import { DataQuery, RawTimeRange, IntervalValues, DataSourceApi } from 'app/types/series'; +import { DataQuery, DataSourceApi } from 'app/types/series'; +import { RawTimeRange, IntervalValues } from '@grafana/ui'; export const DEFAULT_RANGE = { from: 'now-6h', diff --git a/public/app/core/utils/rangeutil.ts b/public/app/core/utils/rangeutil.ts index 0150e80f1ed..310c8ab8533 100644 --- a/public/app/core/utils/rangeutil.ts +++ b/public/app/core/utils/rangeutil.ts @@ -1,7 +1,7 @@ import _ from 'lodash'; import moment from 'moment'; -import { RawTimeRange } from 'app/types/series'; +import { RawTimeRange } from '@grafana/ui'; import * as dateMath from './datemath'; diff --git a/public/app/features/dashboard/dashgrid/DataPanel.tsx b/public/app/features/dashboard/dashgrid/DataPanel.tsx index 2a72b16d60f..30a939b50aa 100644 --- a/public/app/features/dashboard/dashgrid/DataPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DataPanel.tsx @@ -8,8 +8,8 @@ import { getDatasourceSrv, DatasourceSrv } from 'app/features/plugins/datasource import kbn from 'app/core/utils/kbn'; // Types -import { TimeRange, DataQueryOptions, DataQueryResponse, TimeSeries } from 'app/types'; -import { LoadingState } from '@grafana/ui'; +import { DataQueryOptions, DataQueryResponse } from 'app/types'; +import { TimeRange, TimeSeries, LoadingState } from '@grafana/ui'; interface RenderProps { loading: LoadingState; diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.tsx index 5df6f20fc23..94719dfe6e0 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.tsx @@ -16,7 +16,8 @@ import { PANEL_HEADER_HEIGHT } from 'app/core/constants'; // Types import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; -import { PanelPlugin, TimeRange } from 'app/types'; +import { PanelPlugin } from 'app/types'; +import { TimeRange } from '@grafana/ui'; export interface Props { panel: PanelModel; diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx index cde540c0509..1d17ec6cefc 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx @@ -3,7 +3,7 @@ import { DashboardModel } from 'app/features/dashboard/dashboard_model'; import { PanelModel } from 'app/features/dashboard/panel_model'; import { PanelHeaderMenuItem } from './PanelHeaderMenuItem'; import { getPanelMenu } from 'app/features/dashboard/utils/getPanelMenu'; -import { PanelMenuItem } from 'app/types/panel'; +import { PanelMenuItem } from '@grafana/ui'; export interface Props { panel: PanelModel; diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx index 92a64a2f24d..d42b48fe1d6 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx @@ -1,5 +1,5 @@ import React, { SFC } from 'react'; -import { PanelMenuItem } from 'app/types/panel'; +import { PanelMenuItem } from '@grafana/ui'; interface Props { children: any; diff --git a/public/app/features/dashboard/dashgrid/PanelPluginNotFound.tsx b/public/app/features/dashboard/dashgrid/PanelPluginNotFound.tsx index 82008b10d2f..18b307b5ea5 100644 --- a/public/app/features/dashboard/dashgrid/PanelPluginNotFound.tsx +++ b/public/app/features/dashboard/dashgrid/PanelPluginNotFound.tsx @@ -1,6 +1,10 @@ +// Libraries import _ from 'lodash'; import React, { PureComponent } from 'react'; -import { PanelPlugin, PanelProps } from 'app/types'; + +// Types +import { PanelProps } from '@grafana/ui'; +import { PanelPlugin } from 'app/types'; interface Props { pluginId: string; diff --git a/public/app/features/dashboard/time_srv.ts b/public/app/features/dashboard/time_srv.ts index ac717de15c9..b4d18e0279a 100644 --- a/public/app/features/dashboard/time_srv.ts +++ b/public/app/features/dashboard/time_srv.ts @@ -6,9 +6,9 @@ import _ from 'lodash'; import kbn from 'app/core/utils/kbn'; import coreModule from 'app/core/core_module'; import * as dateMath from 'app/core/utils/datemath'; -// Types -import { TimeRange } from 'app/types'; +// Types +import { TimeRange } from '@grafana/ui'; export class TimeSrv { time: any; diff --git a/public/app/features/dashboard/utils/getPanelMenu.ts b/public/app/features/dashboard/utils/getPanelMenu.ts index 07ce54108f3..190451671ad 100644 --- a/public/app/features/dashboard/utils/getPanelMenu.ts +++ b/public/app/features/dashboard/utils/getPanelMenu.ts @@ -4,7 +4,7 @@ import { store } from 'app/store/store'; import { removePanel, duplicatePanel, copyPanel, editPanelJson, sharePanel } from 'app/features/dashboard/utils/panel'; import { PanelModel } from 'app/features/dashboard/panel_model'; import { DashboardModel } from 'app/features/dashboard/dashboard_model'; -import { PanelMenuItem } from 'app/types/panel'; +import { PanelMenuItem } from '@grafana/ui'; export const getPanelMenu = (dashboard: DashboardModel, panel: PanelModel) => { const onViewPanel = () => { diff --git a/public/app/features/dashboard/utils/panel.ts b/public/app/features/dashboard/utils/panel.ts index 0b0f127e2aa..f7ed0efd910 100644 --- a/public/app/features/dashboard/utils/panel.ts +++ b/public/app/features/dashboard/utils/panel.ts @@ -4,7 +4,7 @@ import store from 'app/core/store'; // Models import { DashboardModel } from 'app/features/dashboard/dashboard_model'; import { PanelModel } from 'app/features/dashboard/panel_model'; -import { TimeRange } from 'app/types/series'; +import { TimeRange } from '@grafana/ui'; // Utils import { isString as _isString } from 'lodash'; diff --git a/public/app/features/explore/Explore.tsx b/public/app/features/explore/Explore.tsx index e8897c6926a..f56d9cabd16 100644 --- a/public/app/features/explore/Explore.tsx +++ b/public/app/features/explore/Explore.tsx @@ -11,7 +11,8 @@ import { QueryHintGetter, QueryHint, } from 'app/types/explore'; -import { TimeRange, DataQuery } from 'app/types/series'; +import { TimeRange } from '@grafana/ui'; +import { DataQuery } from 'app/types/series'; import store from 'app/core/store'; import { DEFAULT_RANGE, diff --git a/public/app/features/explore/Graph.tsx b/public/app/features/explore/Graph.tsx index 10f3faa1267..5d64dde28ce 100644 --- a/public/app/features/explore/Graph.tsx +++ b/public/app/features/explore/Graph.tsx @@ -8,7 +8,7 @@ import 'vendor/flot/jquery.flot.time'; import 'vendor/flot/jquery.flot.selection'; import 'vendor/flot/jquery.flot.stack'; -import { RawTimeRange } from 'app/types/series'; +import { RawTimeRange } from '@grafana/ui'; import * as dateMath from 'app/core/utils/datemath'; import TimeSeries from 'app/core/time_series2'; diff --git a/public/app/features/explore/Logs.tsx b/public/app/features/explore/Logs.tsx index 2119f5a96b7..1a384cf011d 100644 --- a/public/app/features/explore/Logs.tsx +++ b/public/app/features/explore/Logs.tsx @@ -4,7 +4,7 @@ import Highlighter from 'react-highlight-words'; import classnames from 'classnames'; import * as rangeUtil from 'app/core/utils/rangeutil'; -import { RawTimeRange } from 'app/types/series'; +import { RawTimeRange } from '@grafana/ui'; import { LogsDedupDescription, LogsDedupStrategy, diff --git a/public/app/features/explore/QueryEditor.tsx b/public/app/features/explore/QueryEditor.tsx index 7ad659ec784..ce0a8a6e03e 100644 --- a/public/app/features/explore/QueryEditor.tsx +++ b/public/app/features/explore/QueryEditor.tsx @@ -3,7 +3,7 @@ import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoa import { Emitter } from 'app/core/utils/emitter'; import { getIntervals } from 'app/core/utils/explore'; import { DataQuery } from 'app/types'; -import { RawTimeRange } from 'app/types/series'; +import { RawTimeRange } from '@grafana/ui'; import { getTimeSrv } from 'app/features/dashboard/time_srv'; import 'app/features/plugins/plugin_loader'; diff --git a/public/app/features/explore/QueryRows.tsx b/public/app/features/explore/QueryRows.tsx index 45a8c48ca22..4101475092b 100644 --- a/public/app/features/explore/QueryRows.tsx +++ b/public/app/features/explore/QueryRows.tsx @@ -7,7 +7,7 @@ import { Emitter } from 'app/core/utils/emitter'; import QueryEditor from './QueryEditor'; import QueryTransactionStatus from './QueryTransactionStatus'; import { DataSource, DataQuery } from 'app/types'; -import { RawTimeRange } from 'app/types/series'; +import { RawTimeRange } from '@grafana/ui'; function getFirstHintFromTransactions(transactions: QueryTransaction[]): QueryHint { const transaction = transactions.find(qt => qt.hints && qt.hints.length > 0); diff --git a/public/app/features/explore/TimePicker.tsx b/public/app/features/explore/TimePicker.tsx index b99618d257a..8476c6b2b27 100644 --- a/public/app/features/explore/TimePicker.tsx +++ b/public/app/features/explore/TimePicker.tsx @@ -3,7 +3,7 @@ import moment from 'moment'; import * as dateMath from 'app/core/utils/datemath'; import * as rangeUtil from 'app/core/utils/rangeutil'; -import { RawTimeRange, TimeRange } from 'app/types/series'; +import { RawTimeRange, TimeRange } from '@grafana/ui'; const DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss'; export const DEFAULT_RANGE = { diff --git a/public/app/plugins/panel/gauge/Threshold.test.tsx b/public/app/plugins/panel/gauge/Threshold.test.tsx index 3b2becd9859..3fa508b98a9 100644 --- a/public/app/plugins/panel/gauge/Threshold.test.tsx +++ b/public/app/plugins/panel/gauge/Threshold.test.tsx @@ -2,7 +2,8 @@ import React from 'react'; import { shallow } from 'enzyme'; import Thresholds from './Thresholds'; import { defaultProps, OptionsProps } from './module'; -import { BasicGaugeColor, PanelOptionsProps } from 'app/types'; +import { BasicGaugeColor } from 'app/types'; +import { PanelOptionsProps } from '@grafana/ui'; const setup = (propOverrides?: object) => { const props: PanelOptionsProps = { diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index 152e7c20b5e..245a17abe52 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -5,15 +5,8 @@ import ValueOptions from './ValueOptions'; import GaugeOptions from './GaugeOptions'; import Thresholds from './Thresholds'; import ValueMappings from './ValueMappings'; -import { - BasicGaugeColor, - NullValueMode, - PanelOptionsProps, - PanelProps, - RangeMap, - Threshold, - ValueMap, -} from 'app/types'; +import { PanelOptionsProps, PanelProps, NullValueMode } from '@grafana/ui'; +import { BasicGaugeColor, RangeMap, Threshold, ValueMap } from 'app/types'; export interface OptionsProps { baseColor: string; diff --git a/public/app/plugins/panel/graph2/GraphOptions.tsx b/public/app/plugins/panel/graph2/GraphOptions.tsx index e87c03da634..6bb4b2c13d5 100644 --- a/public/app/plugins/panel/graph2/GraphOptions.tsx +++ b/public/app/plugins/panel/graph2/GraphOptions.tsx @@ -6,7 +6,7 @@ import React, { PureComponent } from 'react'; import { Switch } from 'app/core/components/Switch/Switch'; // Types -import { PanelOptionsProps } from 'app/types'; +import { PanelOptionsProps } from '@grafana/ui'; import { Options } from './types'; export class GraphOptions extends PureComponent> { diff --git a/public/app/plugins/panel/graph2/GraphPanel.tsx b/public/app/plugins/panel/graph2/GraphPanel.tsx index a7ef45e5428..95dc5a9e620 100644 --- a/public/app/plugins/panel/graph2/GraphPanel.tsx +++ b/public/app/plugins/panel/graph2/GraphPanel.tsx @@ -9,7 +9,7 @@ import Graph from 'app/viz/Graph'; import { getTimeSeriesVMs } from 'app/viz/state/timeSeries'; // Types -import { PanelProps, NullValueMode } from 'app/types'; +import { PanelProps, NullValueMode } from '@grafana/ui'; import { Options } from './types'; interface Props extends PanelProps {} diff --git a/public/app/plugins/panel/text2/module.tsx b/public/app/plugins/panel/text2/module.tsx index aaca23ccbf0..68523ff0880 100644 --- a/public/app/plugins/panel/text2/module.tsx +++ b/public/app/plugins/panel/text2/module.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { PanelProps } from 'app/types'; +import { PanelProps } from '@grafana/ui'; export class Text2 extends PureComponent { constructor(props) { diff --git a/public/app/types/explore.ts b/public/app/types/explore.ts index 80d55eedb60..647b3e99398 100644 --- a/public/app/types/explore.ts +++ b/public/app/types/explore.ts @@ -1,6 +1,7 @@ import { Value } from 'slate'; -import { DataQuery, RawTimeRange } from './series'; +import { DataQuery } from './series'; +import { RawTimeRange } from '@grafana/ui'; import TableModel from 'app/core/table_model'; import { LogsModel } from 'app/core/logs_model'; import { DataSourceSelectItem } from 'app/types/datasources'; diff --git a/public/app/types/index.ts b/public/app/types/index.ts index dd84f4acf7d..ab52b03ab17 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -8,19 +8,8 @@ import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys'; import { Invitee, OrgUser, User, UsersState, UserState } from './user'; import { DataSource, DataSourceSelectItem, DataSourcesState } from './datasources'; -import { - TimeRange, - TimeSeries, - TimeSeriesVM, - TimeSeriesVMs, - TimeSeriesStats, - NullValueMode, - DataQuery, - DataQueryResponse, - DataQueryOptions, - IntervalValues, -} from './series'; -import { BasicGaugeColor, MappingType, PanelProps, PanelOptionsProps, RangeMap, Threshold, ValueMap } from './panel'; +import { DataQuery, DataQueryResponse, DataQueryOptions } from './series'; +import { BasicGaugeColor, MappingType, RangeMap, Threshold, ValueMap } from './panel'; import { PluginDashboard, PluginMeta, Plugin, PanelPlugin, PluginsState } from './plugins'; import { Organization, OrganizationState } from './organization'; import { @@ -67,15 +56,7 @@ export { OrgUser, User, UsersState, - TimeRange, PanelPlugin, - PanelProps, - PanelOptionsProps, - TimeSeries, - TimeSeriesVM, - TimeSeriesVMs, - NullValueMode, - TimeSeriesStats, DataQuery, DataQueryResponse, DataQueryOptions, @@ -93,7 +74,6 @@ export { ValidationRule, ValueMap, RangeMap, - IntervalValues, MappingType, BasicGaugeColor, }; diff --git a/public/app/types/panel.ts b/public/app/types/panel.ts index d5db8256670..31674d20304 100644 --- a/public/app/types/panel.ts +++ b/public/app/types/panel.ts @@ -1,35 +1,3 @@ -import { TimeSeries, TimeRange } from './series'; -import { LoadingState } from '@grafana/ui'; - -export interface PanelProps { - timeSeries: TimeSeries[]; - timeRange: TimeRange; - loading: LoadingState; - options: T; - renderCounter: number; - width: number; - height: number; -} - -export interface PanelOptionsProps { - options: T; - onChange: (options: T) => void; -} - -export interface PanelSize { - width: number; - height: number; -} - -export interface PanelMenuItem { - type?: 'submenu' | 'divider'; - text?: string; - iconClassName?: string; - onClick?: () => void; - shortcut?: string; - subMenu?: PanelMenuItem[]; -} - export interface Threshold { index: number; value: number; diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index a3519e5b5cc..a1403c7a71c 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -1,5 +1,5 @@ import { ComponentClass } from 'react'; -import { PanelProps, PanelOptionsProps } from './panel'; +import { PanelProps, PanelOptionsProps } from '@grafana/ui'; export interface PluginExports { Datasource?: any; diff --git a/public/app/types/series.ts b/public/app/types/series.ts index f7e196a03f5..9fe68955da5 100644 --- a/public/app/types/series.ts +++ b/public/app/types/series.ts @@ -1,68 +1,5 @@ -import { Moment } from 'moment'; import { PluginMeta } from './plugins'; - -export interface RawTimeRange { - from: Moment | string; - to: Moment | string; -} - -export interface TimeRange { - from: Moment; - to: Moment; - raw: RawTimeRange; -} - -export interface IntervalValues { - interval: string; // 10s,5m - intervalMs: number; -} - -export type TimeSeriesValue = string | number | null; - -export type TimeSeriesPoints = TimeSeriesValue[][]; - -export interface TimeSeries { - target: string; - datapoints: TimeSeriesPoints; - unit?: string; -} - -/** View model projection of a time series */ -export interface TimeSeriesVM { - label: string; - color: string; - data: TimeSeriesValue[][]; - stats: TimeSeriesStats; -} - -export interface TimeSeriesStats { - total: number; - max: number; - min: number; - logmin: number; - avg: number | null; - current: number | null; - first: number | null; - delta: number; - diff: number | null; - range: number | null; - timeStep: number; - count: number; - allIsNull: boolean; - allIsZero: boolean; -} - -export enum NullValueMode { - Null = 'null', - Ignore = 'connected', - AsZero = 'null as zero', -} - -/** View model projection of many time series */ -export interface TimeSeriesVMs { - [index: number]: TimeSeriesVM; - length: number; -} +import { TimeSeries, TimeRange, RawTimeRange } from '@grafana/ui'; export interface DataQueryResponse { data: TimeSeries[]; diff --git a/public/app/viz/Gauge.tsx b/public/app/viz/Gauge.tsx index 9907ddf575f..031d856f492 100644 --- a/public/app/viz/Gauge.tsx +++ b/public/app/viz/Gauge.tsx @@ -1,6 +1,7 @@ import React, { PureComponent } from 'react'; import $ from 'jquery'; -import { BasicGaugeColor, MappingType, RangeMap, Threshold, TimeSeriesVMs, ValueMap } from 'app/types'; +import { BasicGaugeColor, MappingType, RangeMap, Threshold, ValueMap } from 'app/types'; +import { TimeSeriesVMs } from '@grafana/ui'; import config from '../core/config'; import kbn from '../core/utils/kbn'; diff --git a/public/app/viz/Graph.tsx b/public/app/viz/Graph.tsx index bdababb3e50..c1330d6ce8a 100644 --- a/public/app/viz/Graph.tsx +++ b/public/app/viz/Graph.tsx @@ -5,7 +5,7 @@ import 'vendor/flot/jquery.flot'; import 'vendor/flot/jquery.flot.time'; // Types -import { TimeRange, TimeSeriesVMs } from 'app/types'; +import { TimeRange, TimeSeriesVMs } from '@grafana/ui'; interface GraphProps { timeSeries: TimeSeriesVMs; diff --git a/public/app/viz/state/timeSeries.ts b/public/app/viz/state/timeSeries.ts index e22cb4681b7..782383957bc 100644 --- a/public/app/viz/state/timeSeries.ts +++ b/public/app/viz/state/timeSeries.ts @@ -5,7 +5,7 @@ import _ from 'lodash'; import colors from 'app/core/utils/colors'; // Types -import { TimeSeries, TimeSeriesVMs, NullValueMode } from 'app/types'; +import { TimeSeries, TimeSeriesVMs, NullValueMode } from '@grafana/ui'; interface Options { timeSeries: TimeSeries[]; From 4b323d98791c3c22f1bff1a22849ec1994cff14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 24 Dec 2018 07:05:18 +0100 Subject: [PATCH 08/13] Moved sass for component to @grafana/ui lib --- .../grafana-ui/src/components/DeleteButton/_DeleteButton.scss | 0 packages/grafana-ui/src/components/index.scss | 1 + packages/grafana-ui/src/index.scss | 1 + packages/grafana-ui/src/utils/colors.ts | 0 public/sass/_grafana.scss | 4 +++- 5 files changed, 5 insertions(+), 1 deletion(-) rename public/sass/components/_delete_button.scss => packages/grafana-ui/src/components/DeleteButton/_DeleteButton.scss (100%) create mode 100644 packages/grafana-ui/src/components/index.scss create mode 100644 packages/grafana-ui/src/index.scss create mode 100644 packages/grafana-ui/src/utils/colors.ts diff --git a/public/sass/components/_delete_button.scss b/packages/grafana-ui/src/components/DeleteButton/_DeleteButton.scss similarity index 100% rename from public/sass/components/_delete_button.scss rename to packages/grafana-ui/src/components/DeleteButton/_DeleteButton.scss diff --git a/packages/grafana-ui/src/components/index.scss b/packages/grafana-ui/src/components/index.scss new file mode 100644 index 00000000000..d52508c946c --- /dev/null +++ b/packages/grafana-ui/src/components/index.scss @@ -0,0 +1 @@ +@import 'DeleteButton/DeleteButton'; diff --git a/packages/grafana-ui/src/index.scss b/packages/grafana-ui/src/index.scss new file mode 100644 index 00000000000..841415620d6 --- /dev/null +++ b/packages/grafana-ui/src/index.scss @@ -0,0 +1 @@ +@import 'components/index'; diff --git a/packages/grafana-ui/src/utils/colors.ts b/packages/grafana-ui/src/utils/colors.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index bc6b024f643..404a212241b 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -38,6 +38,9 @@ @import 'layout/lists'; @import 'layout/page'; +// LOAD @grafana/ui components +@import '../../packages/grafana-ui/src/index'; + // COMPONENTS @import 'components/scrollbar'; @import 'components/cards'; @@ -98,7 +101,6 @@ @import 'components/form_select_box'; @import 'components/panel_editor'; @import 'components/toolbar'; -@import 'components/delete_button'; @import 'components/add_data_source.scss'; @import 'components/page_loader'; @import 'components/thresholds'; From a38490f4b2d0dbe9b17a646572fcaf7d80956c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 24 Dec 2018 14:14:06 +0100 Subject: [PATCH 09/13] wip: moving react graph component to grafana/ui --- packages/grafana-build/README.md | 4 + packages/grafana-build/package.json | 12 ++ packages/grafana-ui/README.md | 3 + packages/grafana-ui/package.json | 8 +- .../src/components/Graph}/Graph.tsx | 4 +- packages/grafana-ui/src/components/index.ts | 1 + packages/grafana-ui/src/index.ts | 1 + packages/grafana-ui/src/types/series.ts | 8 +- packages/grafana-ui/src/utils/colors.ts | 0 packages/grafana-ui/src/utils/index.ts | 1 + .../grafana-ui/src/utils/processTimeSeries.ts | 174 ++++++++++++++++++ .../app/plugins/panel/graph2/GraphPanel.tsx | 8 +- yarn.lock | 9 +- 13 files changed, 218 insertions(+), 15 deletions(-) create mode 100644 packages/grafana-build/README.md create mode 100644 packages/grafana-build/package.json create mode 100644 packages/grafana-ui/README.md rename {public/app/viz => packages/grafana-ui/src/components/Graph}/Graph.tsx (95%) delete mode 100644 packages/grafana-ui/src/utils/colors.ts create mode 100644 packages/grafana-ui/src/utils/index.ts create mode 100644 packages/grafana-ui/src/utils/processTimeSeries.ts diff --git a/packages/grafana-build/README.md b/packages/grafana-build/README.md new file mode 100644 index 00000000000..588d91861d3 --- /dev/null +++ b/packages/grafana-build/README.md @@ -0,0 +1,4 @@ +# Shared build scripts + +Shared build scripts for plugins & internal packages. + diff --git a/packages/grafana-build/package.json b/packages/grafana-build/package.json new file mode 100644 index 00000000000..0bc9340a667 --- /dev/null +++ b/packages/grafana-build/package.json @@ -0,0 +1,12 @@ +{ + "name": "@grafana/build", + "private": true, + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/packages/grafana-ui/README.md b/packages/grafana-ui/README.md new file mode 100644 index 00000000000..1413965f7da --- /dev/null +++ b/packages/grafana-ui/README.md @@ -0,0 +1,3 @@ +# Grafana (WIP) shared component library + +Used by internal & external plugins. diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 0c023817b9f..d4bf80f5dec 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -10,17 +10,19 @@ "author": "", "license": "ISC", "dependencies": { + "@torkelo/react-select": "2.1.1", + "moment": "^2.22.2", "react": "^16.6.3", "react-dom": "^16.6.3", - "react-popper": "^1.3.0", "react-highlight-words": "0.11.0", - "@torkelo/react-select": "2.1.1", + "react-popper": "^1.3.0", "react-transition-group": "^2.2.1", - "moment": "^2.22.2", + "lodash": "^4.17.10", "react-virtualized": "^9.21.0" }, "devDependencies": { "@types/jest": "^23.3.2", + "@types/lodash": "^4.17.10", "@types/react": "^16.7.6", "typescript": "^3.2.2" } diff --git a/public/app/viz/Graph.tsx b/packages/grafana-ui/src/components/Graph/Graph.tsx similarity index 95% rename from public/app/viz/Graph.tsx rename to packages/grafana-ui/src/components/Graph/Graph.tsx index c1330d6ce8a..07edd3f11f0 100644 --- a/public/app/viz/Graph.tsx +++ b/packages/grafana-ui/src/components/Graph/Graph.tsx @@ -1,11 +1,9 @@ // Libraries import $ from 'jquery'; import React, { PureComponent } from 'react'; -import 'vendor/flot/jquery.flot'; -import 'vendor/flot/jquery.flot.time'; // Types -import { TimeRange, TimeSeriesVMs } from '@grafana/ui'; +import { TimeRange, TimeSeriesVMs } from '../../types'; interface GraphProps { timeSeries: TimeSeriesVMs; diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index b57b9bcfdb7..0a750cc970f 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -1 +1,2 @@ export { DeleteButton } from './DeleteButton/DeleteButton'; +export { Graph } from './Graph/Graph'; diff --git a/packages/grafana-ui/src/index.ts b/packages/grafana-ui/src/index.ts index 195d95f598d..974d976bbef 100644 --- a/packages/grafana-ui/src/index.ts +++ b/packages/grafana-ui/src/index.ts @@ -1,2 +1,3 @@ export * from './components'; export * from './types'; +export * from './utils'; diff --git a/packages/grafana-ui/src/types/series.ts b/packages/grafana-ui/src/types/series.ts index 6868ff567c9..49662e9872d 100644 --- a/packages/grafana-ui/src/types/series.ts +++ b/packages/grafana-ui/src/types/series.ts @@ -5,7 +5,7 @@ export enum LoadingState { Error = 'Error', } -export type TimeSeriesValue = string | number | null; +export type TimeSeriesValue = number | null; export type TimeSeriesPoints = TimeSeriesValue[][]; @@ -24,9 +24,9 @@ export interface TimeSeriesVM { } export interface TimeSeriesStats { - total: number; - max: number; - min: number; + total: number | null; + max: number | null; + min: number | null; logmin: number; avg: number | null; current: number | null; diff --git a/packages/grafana-ui/src/utils/colors.ts b/packages/grafana-ui/src/utils/colors.ts deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/packages/grafana-ui/src/utils/index.ts b/packages/grafana-ui/src/utils/index.ts new file mode 100644 index 00000000000..4d9b9a4b948 --- /dev/null +++ b/packages/grafana-ui/src/utils/index.ts @@ -0,0 +1 @@ +export * from './processTimeSeries'; diff --git a/packages/grafana-ui/src/utils/processTimeSeries.ts b/packages/grafana-ui/src/utils/processTimeSeries.ts new file mode 100644 index 00000000000..e92aaf0c1a6 --- /dev/null +++ b/packages/grafana-ui/src/utils/processTimeSeries.ts @@ -0,0 +1,174 @@ +// Libraries +import _ from 'lodash'; + +// Types +import { TimeSeries, TimeSeriesVMs, NullValueMode, TimeSeriesValue } from '../types'; + +interface Options { + timeSeries: TimeSeries[]; + nullValueMode: NullValueMode; + colorPalette: string[]; +} + +export function processTimeSeries({ timeSeries, nullValueMode, colorPalette }: Options): TimeSeriesVMs { + const vmSeries = timeSeries.map((item, index) => { + const colorIndex = index % colorPalette.length; + const label = item.target; + const result = []; + + // stat defaults + let total = 0; + let max: TimeSeriesValue = -Number.MAX_VALUE; + let min: TimeSeriesValue = Number.MAX_VALUE; + let logmin = Number.MAX_VALUE; + let avg: TimeSeriesValue = null; + let current: TimeSeriesValue = null; + let first: TimeSeriesValue = null; + let delta: TimeSeriesValue = 0; + let diff: TimeSeriesValue = null; + let range: TimeSeriesValue = null; + let timeStep = Number.MAX_VALUE; + let allIsNull = true; + let allIsZero = true; + + const ignoreNulls = nullValueMode === NullValueMode.Ignore; + const nullAsZero = nullValueMode === NullValueMode.AsZero; + + let currentTime: TimeSeriesValue = null; + let currentValue: TimeSeriesValue = null; + let nonNulls = 0; + let previousTime: TimeSeriesValue = null; + let previousValue = 0; + let previousDeltaUp = true; + + for (let i = 0; i < item.datapoints.length; i++) { + currentValue = item.datapoints[i][0]; + currentTime = item.datapoints[i][1]; + + if (typeof currentTime !== 'number') { + continue; + } + + if (typeof currentValue !== 'number') { + continue; + } + + // Due to missing values we could have different timeStep all along the series + // so we have to find the minimum one (could occur with aggregators such as ZimSum) + if (previousTime !== null && currentTime !== null) { + const currentStep = currentTime - previousTime; + if (currentStep < timeStep) { + timeStep = currentStep; + } + } + + previousTime = currentTime; + + if (currentValue === null) { + if (ignoreNulls) { + continue; + } + if (nullAsZero) { + currentValue = 0; + } + } + + if (currentValue !== null) { + if (_.isNumber(currentValue)) { + total += currentValue; + allIsNull = false; + nonNulls++; + } + + if (currentValue > max) { + max = currentValue; + } + + if (currentValue < min) { + min = currentValue; + } + + if (first === null) { + first = currentValue; + } else { + if (previousValue > currentValue) { + // counter reset + previousDeltaUp = false; + if (i === item.datapoints.length - 1) { + // reset on last + delta += currentValue; + } + } else { + if (previousDeltaUp) { + delta += currentValue - previousValue; // normal increment + } else { + delta += currentValue; // account for counter reset + } + previousDeltaUp = true; + } + } + previousValue = currentValue; + + if (currentValue < logmin && currentValue > 0) { + logmin = currentValue; + } + + if (currentValue !== 0) { + allIsZero = false; + } + } + + result.push([currentTime, currentValue]); + } + + if (max === -Number.MAX_VALUE) { + max = null; + } + + if (min === Number.MAX_VALUE) { + min = null; + } + + if (result.length && !allIsNull) { + avg = total / nonNulls; + current = result[result.length - 1][1]; + if (current === null && result.length > 1) { + current = result[result.length - 2][1]; + } + } + + if (max !== null && min !== null) { + range = max - min; + } + + if (current !== null && first !== null) { + diff = current - first; + } + + const count = result.length; + + return { + data: result, + label: label, + color: colorPalette[colorIndex], + stats: { + total, + min, + max, + current, + logmin, + avg, + diff, + delta, + timeStep, + range, + count, + first, + allIsZero, + allIsNull, + }, + }; + }); + + return vmSeries; +} diff --git a/public/app/plugins/panel/graph2/GraphPanel.tsx b/public/app/plugins/panel/graph2/GraphPanel.tsx index 95dc5a9e620..eda200e5e82 100644 --- a/public/app/plugins/panel/graph2/GraphPanel.tsx +++ b/public/app/plugins/panel/graph2/GraphPanel.tsx @@ -1,12 +1,13 @@ // Libraries import _ from 'lodash'; import React, { PureComponent } from 'react'; +import colors from 'app/core/utils/colors'; // Components -import Graph from 'app/viz/Graph'; +import { Graph } from '@grafana/ui'; // Services & Utils -import { getTimeSeriesVMs } from 'app/viz/state/timeSeries'; +import { processTimeSeries } from '@grafana/ui'; // Types import { PanelProps, NullValueMode } from '@grafana/ui'; @@ -23,9 +24,10 @@ export class GraphPanel extends PureComponent { const { timeSeries, timeRange, width, height } = this.props; const { showLines, showBars, showPoints } = this.props.options; - const vmSeries = getTimeSeriesVMs({ + const vmSeries = processTimeSeries({ timeSeries: timeSeries, nullValueMode: NullValueMode.Ignore, + colorPalette: colors, }); return ( diff --git a/yarn.lock b/yarn.lock index ecdc347c4f5..c732e576022 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1029,6 +1029,11 @@ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.4.tgz#cc43ae176a91dcb1504839b0b9d6659386cf0af5" integrity sha512-46jSw0QMerCRkhJZbOwPA0Eb9T1p74HtECsfa0GXdgjkenSGhgvK96w+e2PEPu4GF0/brUK5WQKq/rUQQFyAxA== +"@types/lodash@^4.14.119": + version "4.14.119" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.119.tgz#be847e5f4bc3e35e46d041c394ead8b603ad8b39" + integrity sha512-Z3TNyBL8Vd/M9D9Ms2S3LmFq2sSMzahodD6rCS9V2N44HUMINb75jNkSuwAx7eo2ufqTdfOdtGQpNbieUjPQmw== + "@types/node@*": version "10.11.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.4.tgz#e8bd933c3f78795d580ae41d86590bfc1f4f389d" @@ -1083,7 +1088,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@16.7.6", "@types/react@^16.1.0", "@types/react@^16.7.6": +"@types/react@*", "@types/react@^16.1.0", "@types/react@^16.7.6": version "16.7.6" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040" integrity sha512-QBUfzftr/8eg/q3ZRgf/GaDP6rTYc7ZNem+g4oZM38C9vXyV8AWRWaTQuW5yCoZTsfHrN7b3DeEiUnqH9SrnpA== @@ -3153,7 +3158,7 @@ caniuse-api@^1.5.2: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-db@1.0.30000772, caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: +caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: version "1.0.30000772" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000772.tgz#51aae891768286eade4a3d8319ea76d6a01b512b" integrity sha1-UarokXaChureSj2DGep21qAbUSs= From 19da963a194b039766478b8ba6090d5c3e3ee1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 25 Dec 2018 08:55:44 +0100 Subject: [PATCH 10/13] Typings issues --- package.json | 10 +++++++++- packages/grafana-ui/package.json | 5 +++-- packages/grafana-ui/src/components/Graph/Graph.tsx | 10 +++++++--- packages/grafana-ui/src/types/jquery.d.ts | 3 +++ tsconfig.json | 1 + yarn.lock | 5 +++++ 6 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 packages/grafana-ui/src/types/jquery.d.ts diff --git a/package.json b/package.json index 0f0f7fefa83..bb384197b8e 100644 --- a/package.json +++ b/package.json @@ -181,5 +181,13 @@ "caniuse-db": "1.0.30000772", "**/@types/react": "16.7.6" }, - "workspaces": ["packages/grafana-ui"] + "workspaces": { + "packages": [ + "packages/*" + ], + "nohoist": [ + "**/@types/*", + "**/@types/*/**" + ] + } } diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index d4bf80f5dec..fcba8f5f87d 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -11,18 +11,19 @@ "license": "ISC", "dependencies": { "@torkelo/react-select": "2.1.1", + "@types/jquery": "^1.10.35", + "lodash": "^4.17.10", "moment": "^2.22.2", "react": "^16.6.3", "react-dom": "^16.6.3", "react-highlight-words": "0.11.0", "react-popper": "^1.3.0", "react-transition-group": "^2.2.1", - "lodash": "^4.17.10", "react-virtualized": "^9.21.0" }, "devDependencies": { "@types/jest": "^23.3.2", - "@types/lodash": "^4.17.10", + "@types/lodash": "^4.14.119", "@types/react": "^16.7.6", "typescript": "^3.2.2" } diff --git a/packages/grafana-ui/src/components/Graph/Graph.tsx b/packages/grafana-ui/src/components/Graph/Graph.tsx index 07edd3f11f0..51afb33802d 100644 --- a/packages/grafana-ui/src/components/Graph/Graph.tsx +++ b/packages/grafana-ui/src/components/Graph/Graph.tsx @@ -22,7 +22,7 @@ export class Graph extends PureComponent { showBars: false, }; - element: HTMLElement; + element: HTMLElement | null; componentDidUpdate() { this.draw(); @@ -33,6 +33,10 @@ export class Graph extends PureComponent { } draw() { + if (this.element === null) { + return; + } + const { width, timeSeries, timeRange, showLines, showBars, showPoints } = this.props; if (!width) { @@ -74,7 +78,7 @@ export class Graph extends PureComponent { max: max, label: 'Datetime', ticks: ticks, - timeformat: time_format(ticks, min, max), + timeformat: timeFormat(ticks, min, max), }, grid: { minBorderMargin: 0, @@ -107,7 +111,7 @@ export class Graph extends PureComponent { } // Copied from graph.ts -function time_format(ticks, min, max) { +function timeFormat(ticks: number, min: number, max: number): string { if (min && max && ticks) { const range = max - min; const secPerTick = range / ticks / 1000; diff --git a/packages/grafana-ui/src/types/jquery.d.ts b/packages/grafana-ui/src/types/jquery.d.ts new file mode 100644 index 00000000000..e6e1be50edc --- /dev/null +++ b/packages/grafana-ui/src/types/jquery.d.ts @@ -0,0 +1,3 @@ +interface JQueryStatic { + plot: (element: HTMLElement, data: any[], options: any) => void; +} diff --git a/tsconfig.json b/tsconfig.json index 58b29ba428e..3c8c41f34e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,6 +26,7 @@ "noUnusedLocals": true, "baseUrl": "public", "pretty": true, + "typeRoots": ["node_modules/@types", "types"], "paths": { "app": ["app"] } diff --git a/yarn.lock b/yarn.lock index c732e576022..3d267ed3e1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1029,6 +1029,11 @@ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.4.tgz#cc43ae176a91dcb1504839b0b9d6659386cf0af5" integrity sha512-46jSw0QMerCRkhJZbOwPA0Eb9T1p74HtECsfa0GXdgjkenSGhgvK96w+e2PEPu4GF0/brUK5WQKq/rUQQFyAxA== +"@types/jquery@^1.10.35": + version "1.10.35" + resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-1.10.35.tgz#4e5c2b1e5b3bf0b863efb8c5e70081f52e6c9518" + integrity sha512-SVtqEcudm7yjkTwoRA1gC6CNMhGDdMx4Pg8BPdiqI7bXXdCn1BPmtxgeWYQOgDxrq53/5YTlhq5ULxBEAlWIBg== + "@types/lodash@^4.14.119": version "4.14.119" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.119.tgz#be847e5f4bc3e35e46d041c394ead8b603ad8b39" From 493714c27dfbe8c14199e607feecbb5446d50c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 25 Dec 2018 09:59:23 +0100 Subject: [PATCH 11/13] Fixed JQuery typing issues --- package.json | 24 +++++++++++++------ packages/grafana-build/package.json | 3 ++- packages/grafana-ui/src/types/jquery.d.ts | 16 ++++++++++++- public/app/core/directives/tags.ts | 4 ++-- .../plugins/panel/graph/specs/graph.test.ts | 1 + public/app/types/jquery.d.ts | 17 +++++++++++++ yarn.lock | 4 ++-- 7 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 public/app/types/jquery.d.ts diff --git a/package.json b/package.json index bb384197b8e..189ff637d4b 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,11 @@ }, "devDependencies": { "@babel/core": "^7.1.2", - "@rtsao/plugin-proposal-class-properties": "^7.0.1-patch.1", "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/preset-env": "^7.1.0", "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.1.0", + "@rtsao/plugin-proposal-class-properties": "^7.0.1-patch.1", "@types/d3": "^4.10.1", "@types/enzyme": "^3.1.13", "@types/jest": "^23.3.2", @@ -25,6 +25,7 @@ "@types/react-custom-scrollbars": "^4.0.5", "@types/react-dom": "^16.0.9", "@types/react-select": "^2.0.4", + "@types/jquery": "^1.10.35", "angular-mocks": "1.6.6", "autoprefixer": "^6.4.0", "axios": "^0.17.1", @@ -116,9 +117,18 @@ "precommit": "lint-staged && grunt precommit" }, "lint-staged": { - "*.{ts,tsx}": ["prettier --write", "git add"], - "*.scss": ["prettier --write", "git add"], - "*pkg/**/*.go": ["gofmt -w -s", "git add"] + "*.{ts,tsx}": [ + "prettier --write", + "git add" + ], + "*.scss": [ + "prettier --write", + "git add" + ], + "*pkg/**/*.go": [ + "gofmt -w -s", + "git add" + ] }, "prettier": { "trailingComma": "es5", @@ -128,6 +138,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/polyfill": "^7.0.0", + "@torkelo/react-select": "2.1.1", "angular": "1.6.6", "angular-bindonce": "0.3.1", "angular-native-dragdrop": "1.2.2", @@ -154,10 +165,9 @@ "react-custom-scrollbars": "^4.2.1", "react-dom": "^16.6.3", "react-grid-layout": "0.16.6", - "react-popper": "^1.3.0", "react-highlight-words": "0.11.0", + "react-popper": "^1.3.0", "react-redux": "^5.0.7", - "@torkelo/react-select": "2.1.1", "react-sizeme": "^2.3.6", "react-table": "^6.8.6", "react-transition-group": "^2.2.1", @@ -181,7 +191,7 @@ "caniuse-db": "1.0.30000772", "**/@types/react": "16.7.6" }, - "workspaces": { + "workspaces": { "packages": [ "packages/*" ], diff --git a/packages/grafana-build/package.json b/packages/grafana-build/package.json index 0bc9340a667..24fb648c8d4 100644 --- a/packages/grafana-build/package.json +++ b/packages/grafana-build/package.json @@ -5,7 +5,8 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "tslint": "echo \"Nothing to do\"", + "typecheck": "echo \"Nothing to do\"" }, "author": "", "license": "ISC" diff --git a/packages/grafana-ui/src/types/jquery.d.ts b/packages/grafana-ui/src/types/jquery.d.ts index e6e1be50edc..4a6f60b6029 100644 --- a/packages/grafana-ui/src/types/jquery.d.ts +++ b/packages/grafana-ui/src/types/jquery.d.ts @@ -1,3 +1,17 @@ +interface JQueryPlot { + (element: HTMLElement | JQuery, data: any, options: any): void; + plugins: any[]; +} + interface JQueryStatic { - plot: (element: HTMLElement, data: any[], options: any) => void; + plot: JQueryPlot; +} + +interface JQuery { + place_tt: any; + modal: any; + tagsinput: any; + typeahead: any; + accessKey: any; + tooltip: any; } diff --git a/public/app/core/directives/tags.ts b/public/app/core/directives/tags.ts index 33a2252a683..27bddfb1883 100644 --- a/public/app/core/directives/tags.ts +++ b/public/app/core/directives/tags.ts @@ -69,7 +69,7 @@ function bootstrapTagsinput() { }, }); - select.on('itemAdded', event => { + select.on('itemAdded', (event: any) => { if (scope.model.indexOf(event.item) === -1) { scope.model.push(event.item); if (scope.onTagsUpdated) { @@ -85,7 +85,7 @@ function bootstrapTagsinput() { setColor(event.item, tagElement); }); - select.on('itemRemoved', event => { + select.on('itemRemoved', (event: any) => { const idx = scope.model.indexOf(event.item); if (idx !== -1) { scope.model.splice(idx, 1); diff --git a/public/app/plugins/panel/graph/specs/graph.test.ts b/public/app/plugins/panel/graph/specs/graph.test.ts index be243587820..58a35ea2a5f 100644 --- a/public/app/plugins/panel/graph/specs/graph.test.ts +++ b/public/app/plugins/panel/graph/specs/graph.test.ts @@ -114,6 +114,7 @@ describe('grafanaGraph', () => { {} ); + // @ts-ignore $.plot = ctrl.plot = jest.fn(); scope.ctrl = ctrl; diff --git a/public/app/types/jquery.d.ts b/public/app/types/jquery.d.ts new file mode 100644 index 00000000000..4a6f60b6029 --- /dev/null +++ b/public/app/types/jquery.d.ts @@ -0,0 +1,17 @@ +interface JQueryPlot { + (element: HTMLElement | JQuery, data: any, options: any): void; + plugins: any[]; +} + +interface JQueryStatic { + plot: JQueryPlot; +} + +interface JQuery { + place_tt: any; + modal: any; + tagsinput: any; + typeahead: any; + accessKey: any; + tooltip: any; +} diff --git a/yarn.lock b/yarn.lock index 3d267ed3e1d..8066618bb41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1093,7 +1093,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.1.0", "@types/react@^16.7.6": +"@types/react@*", "@types/react@16.7.6", "@types/react@^16.1.0", "@types/react@^16.7.6": version "16.7.6" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040" integrity sha512-QBUfzftr/8eg/q3ZRgf/GaDP6rTYc7ZNem+g4oZM38C9vXyV8AWRWaTQuW5yCoZTsfHrN7b3DeEiUnqH9SrnpA== @@ -3163,7 +3163,7 @@ caniuse-api@^1.5.2: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: +caniuse-db@1.0.30000772, caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: version "1.0.30000772" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000772.tgz#51aae891768286eade4a3d8319ea76d6a01b512b" integrity sha1-UarokXaChureSj2DGep21qAbUSs= From 2dfa3269c3d235ceadb06e955a995fb77e68b3b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 25 Dec 2018 10:20:20 +0100 Subject: [PATCH 12/13] created visualizations folder --- packages/grafana-ui/src/components/index.ts | 1 - packages/grafana-ui/src/index.ts | 1 + .../src/{components => visualizations}/Graph/Graph.tsx | 0 packages/grafana-ui/src/visualizations/index.ts | 1 + public/app/plugins/panel/graph2/GraphPanel.tsx | 10 ++-------- 5 files changed, 4 insertions(+), 9 deletions(-) rename packages/grafana-ui/src/{components => visualizations}/Graph/Graph.tsx (100%) create mode 100644 packages/grafana-ui/src/visualizations/index.ts diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index 0a750cc970f..b57b9bcfdb7 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -1,2 +1 @@ export { DeleteButton } from './DeleteButton/DeleteButton'; -export { Graph } from './Graph/Graph'; diff --git a/packages/grafana-ui/src/index.ts b/packages/grafana-ui/src/index.ts index 974d976bbef..f26af66035b 100644 --- a/packages/grafana-ui/src/index.ts +++ b/packages/grafana-ui/src/index.ts @@ -1,3 +1,4 @@ export * from './components'; +export * from './visualizations'; export * from './types'; export * from './utils'; diff --git a/packages/grafana-ui/src/components/Graph/Graph.tsx b/packages/grafana-ui/src/visualizations/Graph/Graph.tsx similarity index 100% rename from packages/grafana-ui/src/components/Graph/Graph.tsx rename to packages/grafana-ui/src/visualizations/Graph/Graph.tsx diff --git a/packages/grafana-ui/src/visualizations/index.ts b/packages/grafana-ui/src/visualizations/index.ts new file mode 100644 index 00000000000..967432d37c9 --- /dev/null +++ b/packages/grafana-ui/src/visualizations/index.ts @@ -0,0 +1 @@ +export { Graph } from './Graph/Graph'; diff --git a/public/app/plugins/panel/graph2/GraphPanel.tsx b/public/app/plugins/panel/graph2/GraphPanel.tsx index eda200e5e82..a08276e5179 100644 --- a/public/app/plugins/panel/graph2/GraphPanel.tsx +++ b/public/app/plugins/panel/graph2/GraphPanel.tsx @@ -3,14 +3,8 @@ import _ from 'lodash'; import React, { PureComponent } from 'react'; import colors from 'app/core/utils/colors'; -// Components -import { Graph } from '@grafana/ui'; - -// Services & Utils -import { processTimeSeries } from '@grafana/ui'; - -// Types -import { PanelProps, NullValueMode } from '@grafana/ui'; +// Components & Types +import { Graph, PanelProps, NullValueMode, processTimeSeries } from '@grafana/ui'; import { Options } from './types'; interface Props extends PanelProps {} From 98d26354c14db5f1a86e2026a53519daf5d683df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 25 Dec 2018 11:42:23 +0100 Subject: [PATCH 13/13] Added a form component to @grafana/ui --- package.json | 9 ++-- packages/grafana-ui/package.json | 5 ++- .../src/forms/GfFormLabel/GfFormLabel.tsx | 23 ++++++++++ packages/grafana-ui/src/forms/index.ts | 1 + packages/grafana-ui/src/index.ts | 1 + public/app/core/components/Form/Element.tsx | 43 ------------------- public/app/core/components/Form/Label.tsx | 19 -------- public/app/core/components/Form/index.ts | 2 - .../app/features/alerting/AlertRuleItem.tsx | 6 +-- .../dashboard/dashgrid/QueryOptions.tsx | 3 +- .../features/datasources/DataSourcesList.tsx | 2 +- public/app/features/plugins/PluginList.tsx | 2 +- public/app/features/users/UsersActionBar.tsx | 2 +- yarn.lock | 9 +++- 14 files changed, 49 insertions(+), 78 deletions(-) create mode 100644 packages/grafana-ui/src/forms/GfFormLabel/GfFormLabel.tsx create mode 100644 packages/grafana-ui/src/forms/index.ts delete mode 100644 public/app/core/components/Form/Element.tsx delete mode 100644 public/app/core/components/Form/Label.tsx diff --git a/package.json b/package.json index 189ff637d4b..481ec1959ed 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,13 @@ "@types/d3": "^4.10.1", "@types/enzyme": "^3.1.13", "@types/jest": "^23.3.2", + "@types/jquery": "^1.10.35", "@types/node": "^8.0.31", "@types/react": "^16.7.6", "@types/react-custom-scrollbars": "^4.0.5", "@types/react-dom": "^16.0.9", "@types/react-select": "^2.0.4", - "@types/jquery": "^1.10.35", + "@types/classnames": "^2.2.6", "angular-mocks": "1.6.6", "autoprefixer": "^6.4.0", "axios": "^0.17.1", @@ -94,6 +95,7 @@ "tslib": "^1.9.3", "tslint": "^5.8.0", "tslint-loader": "^3.5.3", + "tslint-react": "^3.6.0", "typescript": "^3.0.3", "uglifyjs-webpack-plugin": "^1.2.7", "webpack": "4.19.1", @@ -146,7 +148,7 @@ "angular-sanitize": "1.6.6", "baron": "^3.0.3", "brace": "^0.10.0", - "classnames": "^2.2.5", + "classnames": "^2.2.6", "clipboard": "^1.7.1", "d3": "^4.11.0", "d3-scale-chromatic": "^1.3.0", @@ -184,8 +186,7 @@ "slate-react": "^0.12.4", "tether": "^1.4.0", "tether-drop": "https://github.com/torkelo/drop/tarball/master", - "tinycolor2": "^1.4.1", - "tslint-react": "^3.6.0" + "tinycolor2": "^1.4.1" }, "resolutions": { "caniuse-db": "1.0.30000772", diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index fcba8f5f87d..2fb210e3b46 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -11,7 +11,8 @@ "license": "ISC", "dependencies": { "@torkelo/react-select": "2.1.1", - "@types/jquery": "^1.10.35", + "classnames": "^2.2.5", + "jquery": "^3.2.1", "lodash": "^4.17.10", "moment": "^2.22.2", "react": "^16.6.3", @@ -25,6 +26,8 @@ "@types/jest": "^23.3.2", "@types/lodash": "^4.14.119", "@types/react": "^16.7.6", + "@types/classnames": "^2.2.6", + "@types/jquery": "^1.10.35", "typescript": "^3.2.2" } } diff --git a/packages/grafana-ui/src/forms/GfFormLabel/GfFormLabel.tsx b/packages/grafana-ui/src/forms/GfFormLabel/GfFormLabel.tsx new file mode 100644 index 00000000000..8b80de64696 --- /dev/null +++ b/packages/grafana-ui/src/forms/GfFormLabel/GfFormLabel.tsx @@ -0,0 +1,23 @@ +import React, { SFC, ReactNode } from 'react'; +import classNames from 'classnames'; + +interface Props { + children: ReactNode; + htmlFor?: string; + className?: string; + isFocused?: boolean; + isInvalid?: boolean; +} + +export const GfFormLabel: SFC = ({ children, isFocused, isInvalid, className, htmlFor, ...rest }) => { + const classes = classNames('gf-form-label', className, { + 'gf-form-label--is-focused': isFocused, + 'gf-form-label--is-invalid': isInvalid, + }); + + return ( + + ); +}; diff --git a/packages/grafana-ui/src/forms/index.ts b/packages/grafana-ui/src/forms/index.ts new file mode 100644 index 00000000000..bb6998b0025 --- /dev/null +++ b/packages/grafana-ui/src/forms/index.ts @@ -0,0 +1 @@ +export { GfFormLabel } from './GfFormLabel/GfFormLabel'; diff --git a/packages/grafana-ui/src/index.ts b/packages/grafana-ui/src/index.ts index f26af66035b..b22152497b9 100644 --- a/packages/grafana-ui/src/index.ts +++ b/packages/grafana-ui/src/index.ts @@ -2,3 +2,4 @@ export * from './components'; export * from './visualizations'; export * from './types'; export * from './utils'; +export * from './forms'; diff --git a/public/app/core/components/Form/Element.tsx b/public/app/core/components/Form/Element.tsx deleted file mode 100644 index 997d7f0e717..00000000000 --- a/public/app/core/components/Form/Element.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { PureComponent, ReactNode, ReactElement } from 'react'; -import { Label } from './Label'; -import { uniqueId } from 'lodash'; - -interface Props { - label?: ReactNode; - labelClassName?: string; - id?: string; - children: ReactElement; -} - -export class Element extends PureComponent { - elementId: string = this.props.id || uniqueId('form-element-'); - - get elementLabel() { - const { label, labelClassName } = this.props; - - if (label) { - return ( - - ); - } - - return null; - } - - get children() { - const { children } = this.props; - - return React.cloneElement(children, { id: this.elementId }); - } - - render() { - return ( -
- {this.elementLabel} - {this.children} -
- ); - } -} diff --git a/public/app/core/components/Form/Label.tsx b/public/app/core/components/Form/Label.tsx deleted file mode 100644 index 385a1b325be..00000000000 --- a/public/app/core/components/Form/Label.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React, { PureComponent, ReactNode } from 'react'; - -interface Props { - children: ReactNode; - htmlFor?: string; - className?: string; -} - -export class Label extends PureComponent { - render() { - const { children, htmlFor, className } = this.props; - - return ( - - ); - } -} diff --git a/public/app/core/components/Form/index.ts b/public/app/core/components/Form/index.ts index e4c8197aaa9..6322cf3241a 100644 --- a/public/app/core/components/Form/index.ts +++ b/public/app/core/components/Form/index.ts @@ -1,3 +1 @@ -export { Element } from './Element'; export { Input } from './Input'; -export { Label } from './Label'; diff --git a/public/app/features/alerting/AlertRuleItem.tsx b/public/app/features/alerting/AlertRuleItem.tsx index f47a6348303..86bb0207460 100644 --- a/public/app/features/alerting/AlertRuleItem.tsx +++ b/public/app/features/alerting/AlertRuleItem.tsx @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import Highlighter from 'react-highlight-words'; -import classNames from 'classnames/bind'; +import classNames from 'classnames'; import { AlertRule } from '../../types'; export interface Props { @@ -23,7 +23,7 @@ class AlertRuleItem extends PureComponent { render() { const { rule, onTogglePause } = this.props; - const stateClass = classNames({ + const iconClassName = classNames({ fa: true, 'fa-play': rule.state === 'paused', 'fa-pause': rule.state !== 'paused', @@ -55,7 +55,7 @@ class AlertRuleItem extends PureComponent { title="Pausing an alert rule prevents it from executing" onClick={onTogglePause} > - + diff --git a/public/app/features/dashboard/dashgrid/QueryOptions.tsx b/public/app/features/dashboard/dashgrid/QueryOptions.tsx index dd084418c40..fad70d92990 100644 --- a/public/app/features/dashboard/dashgrid/QueryOptions.tsx +++ b/public/app/features/dashboard/dashgrid/QueryOptions.tsx @@ -10,6 +10,7 @@ import { Input } from 'app/core/components/Form'; import { EventsWithValidation } from 'app/core/components/Form/Input'; import { InputStatus } from 'app/core/components/Form/Input'; import DataSourceOption from './DataSourceOption'; +import { GfFormLabel } from '@grafana/ui'; // Types import { PanelModel } from '../panel_model'; @@ -163,7 +164,7 @@ export class QueryOptions extends PureComponent { {this.renderOptions()}
- Relative time + Relative time