From ec492e55dce5de40732a33e98723840517fe808c Mon Sep 17 00:00:00 2001 From: Tobias Skarhed Date: Tue, 20 Aug 2019 17:19:21 +0200 Subject: [PATCH] Refactor: EmptyListCTA (#18516) * Rewrite EmptyListCTA props and start removing css classes * Add watchDepth onClick * EmptyListCTA with React in annotaitons/editor * Begin conversion of DashLinks editor EmptyListCTA * Use React component in DashLinks, Variables and TeamGroupSync * Remove scss file and add emotion styles * Update snapshot * Remove style import * Fix feedback * Update snapshot --- public/app/core/angular_wrappers.ts | 14 ++- .../components/EmptyListCTA/EmptyListCTA.tsx | 97 +++++++++++++------ public/app/features/alerting/AlertTab.tsx | 2 +- .../app/features/annotations/editor_ctrl.ts | 23 ++++- .../features/annotations/partials/editor.html | 28 +----- public/app/features/api-keys/ApiKeysPage.tsx | 17 ++-- .../__snapshots__/ApiKeysPage.test.tsx.snap | 19 ++-- .../DashLinks/DashLinksEditorCtrl.ts | 17 +++- .../components/DashLinks/editor.html | 17 +--- .../datasources/DataSourcesListPage.tsx | 2 +- public/app/features/teams/TeamGroupSync.tsx | 28 +++--- public/app/features/teams/TeamList.tsx | 18 ++-- .../__snapshots__/TeamGroupSync.test.tsx.snap | 44 ++------- public/app/features/templating/editor_ctrl.ts | 22 +++++ .../features/templating/partials/editor.html | 28 ++---- public/sass/_grafana.scss | 1 - public/sass/components/_empty_list_cta.scss | 24 ----- 17 files changed, 196 insertions(+), 205 deletions(-) delete mode 100644 public/sass/components/_empty_list_cta.scss diff --git a/public/app/core/angular_wrappers.ts b/public/app/core/angular_wrappers.ts index 86249c670d6..ed03aa9e65c 100644 --- a/public/app/core/angular_wrappers.ts +++ b/public/app/core/angular_wrappers.ts @@ -18,7 +18,19 @@ export function registerAngularDirectives() { react2AngularDirective('functionEditor', FunctionEditor, ['func', 'onRemove', 'onMoveLeft', 'onMoveRight']); react2AngularDirective('appNotificationsList', AppNotificationList, []); react2AngularDirective('pageHeader', PageHeader, ['model', 'noTabs']); - react2AngularDirective('emptyListCta', EmptyListCTA, ['model']); + react2AngularDirective('emptyListCta', EmptyListCTA, [ + 'title', + 'buttonIcon', + 'buttonLink', + 'buttonTitle', + ['onClick', { watchDepth: 'reference', wrapApply: true }], + 'proTip', + 'proTipLink', + 'proTipLinkTitle', + 'proTipTarget', + 'infoBox', + 'infoBoxTitle', + ]); react2AngularDirective('searchField', SearchField, [ 'query', 'autoFocus', diff --git a/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx b/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx index 8ad122f60ab..f5df3d090d7 100644 --- a/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx +++ b/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx @@ -1,38 +1,71 @@ -import React, { useContext } from 'react'; +import React, { useContext, MouseEvent } from 'react'; import { CallToActionCard, LinkButton, ThemeContext } from '@grafana/ui'; import { css } from 'emotion'; export interface Props { - model: any; + title: string; + buttonIcon: string; + buttonLink?: string; + buttonTitle: string; + onClick?: (event: MouseEvent) => void; + proTip?: string; + proTipLink?: string; + proTipLinkTitle?: string; + proTipTarget?: string; + infoBox?: { __html: string }; + infoBoxTitle?: string; } -const EmptyListCTA: React.FunctionComponent = props => { +const ctaStyle = css` + text-align: center; +`; + +const infoBoxStyles = css` + max-width: 700px; + margin: 0 auto; +`; + +const EmptyListCTA: React.FunctionComponent = ({ + title, + buttonIcon, + buttonLink, + buttonTitle, + onClick, + proTip, + proTipLink, + proTipLinkTitle, + proTipTarget, + infoBox, + infoBoxTitle, +}) => { const theme = useContext(ThemeContext); - const { - title, - buttonIcon, - buttonLink, - buttonTitle, - onClick, - proTip, - proTipLink, - proTipLinkTitle, - proTipTarget, - } = props.model; + const footer = () => { + return ( + <> + {proTip ? ( + + + <> ProTip: {proTip} + + {proTipLinkTitle} + + + ) : ( + '' + )} + {infoBox ? ( +
+ {infoBoxTitle &&
{infoBoxTitle}
} +
+
+ ) : ( + '' + )} + + ); + }; - const footer = proTip ? ( - - - <> ProTip: {proTip} - - {proTipLinkTitle} - - - ) : ( - '' - ); - - const ctaElementClassName = !footer + const ctaElementClassName = !footer() ? css` margin-bottom: 20px; ` @@ -44,7 +77,15 @@ const EmptyListCTA: React.FunctionComponent = props => { ); - return ; + return ( + + ); }; export default EmptyListCTA; diff --git a/public/app/features/alerting/AlertTab.tsx b/public/app/features/alerting/AlertTab.tsx index 2f293010b90..43857304cbf 100644 --- a/public/app/features/alerting/AlertTab.tsx +++ b/public/app/features/alerting/AlertTab.tsx @@ -142,7 +142,7 @@ export class AlertTab extends PureComponent { <>
(this.element = element)} /> - {!alert && } + {!alert && } ); diff --git a/public/app/features/annotations/editor_ctrl.ts b/public/app/features/annotations/editor_ctrl.ts index d657711a3d2..971809055d4 100644 --- a/public/app/features/annotations/editor_ctrl.ts +++ b/public/app/features/annotations/editor_ctrl.ts @@ -23,6 +23,25 @@ export class AnnotationsEditorCtrl { hide: false, }; + emptyListCta = { + title: 'There are no custom annotation queries added yet', + buttonIcon: 'gicon gicon-annotation', + buttonTitle: 'Add Annotation Query', + infoBox: { + __html: `

Annotations provide a way to integrate event data into your graphs. They are visualized as vertical lines + and icons on all graph panels. When you hover over an annotation icon you can get event text & tags for + the event. You can add annotation events directly from grafana by holding CTRL or CMD + click on graph (or + drag region). These will be stored in Grafana's annotation database. +

+ Checkout the + Annotations documentation + for more information.`, + }, + infoBoxTitle: 'What are annotations?', + }; + showOptions: any = [{ text: 'All Panels', value: 0 }, { text: 'Specific Panels', value: 1 }]; /** @ngInject */ @@ -63,10 +82,10 @@ export class AnnotationsEditorCtrl { this.mode = 'list'; } - setupNew() { + setupNew = () => { this.mode = 'new'; this.reset(); - } + }; backToList() { this.mode = 'list'; diff --git a/public/app/features/annotations/partials/editor.html b/public/app/features/annotations/partials/editor.html index 455b41be193..ff80f061d2b 100644 --- a/public/app/features/annotations/partials/editor.html +++ b/public/app/features/annotations/partials/editor.html @@ -13,10 +13,10 @@ class="btn btn-primary" ng-click="ctrl.setupNew();" ng-if="ctrl.annotations.length > 1" - ng-hide="ctrl.mode === 'edit' || ctrl.mode === 'new'"> - New - + New +
@@ -62,27 +62,7 @@
-
-
There are no custom annotation queries added yet
- - - Add Annotation Query - -
-
What are Annotations?
-

- Annotations provide a way to integrate event data into your graphs. They are visualized as vertical lines - and icons on all graph panels. When you hover over an annotation icon you can get event text & tags for - the event. You can add annotation events directly from grafana by holding CTRL or CMD + click on graph (or - drag region). These will be stored in Grafana's annotation database. -

- Checkout the - Annotations documentation - for more information. -
-
+
diff --git a/public/app/features/api-keys/ApiKeysPage.tsx b/public/app/features/api-keys/ApiKeysPage.tsx index 2656a5e4a7e..c35c8c0686f 100644 --- a/public/app/features/api-keys/ApiKeysPage.tsx +++ b/public/app/features/api-keys/ApiKeysPage.tsx @@ -145,17 +145,12 @@ export class ApiKeysPage extends PureComponent { <> {!isAdding && ( )} {this.renderAddApiKeyForm()} diff --git a/public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap b/public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap index 634dd9738d1..3545395237a 100644 --- a/public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap +++ b/public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap @@ -36,19 +36,12 @@ exports[`Render should render CTA if there are no API keys 1`] = ` isLoading={false} > + Dashboard Links allow you to place links to other dashboards and web sites directly in below the dashboard + header. +

`, + }, + infoBoxTitle: 'What are Dashboard Links?', + }; + /** @ngInject */ constructor($scope: any, $rootScope: any) { this.iconMap = iconMap; @@ -33,10 +46,10 @@ export class DashLinksEditorCtrl { this.mode = 'list'; } - setupNew() { + setupNew = () => { this.mode = 'new'; this.link = { type: 'dashboards', icon: 'external link' }; - } + }; addLink() { this.dashboard.links.push(this.link); diff --git a/public/app/features/dashboard/components/DashLinks/editor.html b/public/app/features/dashboard/components/DashLinks/editor.html index ec08b3a4a76..d71d14d756a 100644 --- a/public/app/features/dashboard/components/DashLinks/editor.html +++ b/public/app/features/dashboard/components/DashLinks/editor.html @@ -19,22 +19,7 @@
-
-
- There are no dashboard links added yet -
- - - Add Dashboard Link - -
-
What are Dashboard Links?
-

- Dashboard Links allow you to place links to other dashboards and web sites directly in below the dashboard - header. -

-
-
+
diff --git a/public/app/features/datasources/DataSourcesListPage.tsx b/public/app/features/datasources/DataSourcesListPage.tsx index c9f6f5b149b..4c0ef5c9d7d 100644 --- a/public/app/features/datasources/DataSourcesListPage.tsx +++ b/public/app/features/datasources/DataSourcesListPage.tsx @@ -79,7 +79,7 @@ export class DataSourcesListPage extends PureComponent { <> - {hasFetched && dataSourcesCount === 0 && } + {hasFetched && dataSourcesCount === 0 && } {hasFetched && dataSourcesCount > 0 && [ { {groups.length === 0 && !isAdding && ( -
-
There are no external groups to sync with
- -
- {headerTooltip} - - Learn more - -
-
+ )} {groups.length > 0 && ( diff --git a/public/app/features/teams/TeamList.tsx b/public/app/features/teams/TeamList.tsx index a85033eee15..445c039d3a3 100644 --- a/public/app/features/teams/TeamList.tsx +++ b/public/app/features/teams/TeamList.tsx @@ -75,16 +75,14 @@ export class TeamList extends PureComponent { renderEmptyList() { return ( ); } diff --git a/public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap b/public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap index 5527479d1dc..32abc277b39 100644 --- a/public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap +++ b/public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap @@ -72,40 +72,16 @@ exports[`Render should render component 1`] = `
-
-
- There are no external groups to sync with -
- -
- - - Sync LDAP or OAuth groups with your Grafana teams. - - Learn more - -
-
+
`; diff --git a/public/app/features/templating/editor_ctrl.ts b/public/app/features/templating/editor_ctrl.ts index 3547e6bd424..24586334162 100644 --- a/public/app/features/templating/editor_ctrl.ts +++ b/public/app/features/templating/editor_ctrl.ts @@ -14,6 +14,24 @@ export class VariableEditorCtrl { $scope.namePattern = /^(?!__).*$/; $scope._ = _; $scope.optionsLimit = 20; + $scope.emptyListCta = { + title: 'There are no variables yet', + buttonTitle: 'Add variable', + buttonIcon: 'gicon gicon-variable', + infoBox: { + __html: `

+ Variables enable more interactive and dynamic dashboards. Instead of hard-coding things like server or + sensor names in your metric queries you can use variables in their place. Variables are shown as dropdown + select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in + your dashboard. Check out the + + Templating documentation + + for more information. +

`, + infoBoxTitle: 'What do variables do?', + }, + }; $scope.refreshOptions = [ { value: 0, text: 'Never' }, @@ -50,6 +68,10 @@ export class VariableEditorCtrl { $scope.mode = mode; }; + $scope.setNewMode = () => { + $scope.setMode('new'); + }; + $scope.add = () => { if ($scope.isValid()) { variableSrv.addVariable($scope.current); diff --git a/public/app/features/templating/partials/editor.html b/public/app/features/templating/partials/editor.html index 6c5d0cfccf6..c3d6f09707c 100644 --- a/public/app/features/templating/partials/editor.html +++ b/public/app/features/templating/partials/editor.html @@ -19,26 +19,14 @@
-
-
There are no variables added yet
- - - Add variable - -
-
What do variables do?
-

- Variables enable more interactive and dynamic dashboards. Instead of hard-coding things like server or - sensor names in your metric queries you can use variables in their place. Variables are shown as dropdown - select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in - your dashboard. Check out the - - Templating documentation - - for more information. -

-
-
+
diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index c94d6b7de70..131d9bf4b7f 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -90,7 +90,6 @@ @import 'components/dashboard_list'; @import 'components/page_header'; @import 'components/dashboard_settings'; -@import 'components/empty_list_cta'; @import 'components/panel_editor'; @import 'components/toolbar'; @import 'components/add_data_source.scss'; diff --git a/public/sass/components/_empty_list_cta.scss b/public/sass/components/_empty_list_cta.scss deleted file mode 100644 index 9430561d195..00000000000 --- a/public/sass/components/_empty_list_cta.scss +++ /dev/null @@ -1,24 +0,0 @@ -.empty-list-cta { - background-color: $empty-list-cta-bg; - text-align: center; - padding: $spacer * 2; - border-radius: $border-radius; - - .grafana-info-box { - max-width: 700px; - margin: 0 auto; - } -} - -.empty-list-cta__title { - padding-bottom: $spacer * 3; - font-style: italic; -} - -.empty-list-cta__button { - margin-bottom: $spacer * 3; -} - -.empty-list-cta__pro-tip-link { - margin-left: 5px; -}