diff --git a/packages/grafana-data/src/types/OptionsUIRegistryBuilder.ts b/packages/grafana-data/src/types/OptionsUIRegistryBuilder.ts index d0f26f0ec0a..24ca250d97b 100644 --- a/packages/grafana-data/src/types/OptionsUIRegistryBuilder.ts +++ b/packages/grafana-data/src/types/OptionsUIRegistryBuilder.ts @@ -40,7 +40,7 @@ export interface OptionsEditorItem ex * * @param currentConfig Current options values */ - showIf?: (currentConfig: TOptions) => boolean; + showIf?: (currentConfig: TOptions) => boolean | undefined; /** * Function that returns number of items if given option represents a collection, i.e. array of items. * @param value diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 8e4391a42b5..081eeb269de 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -428,7 +428,7 @@ export interface DataQueryRequest { intervalMs?: number; maxDataPoints?: number; panelId: number; - range?: TimeRange; + range: TimeRange; reverse?: boolean; scopedVars: ScopedVars; targets: TQuery[]; diff --git a/packages/grafana-data/src/types/panel.ts b/packages/grafana-data/src/types/panel.ts index e2a73d42fd7..a79220dda8a 100644 --- a/packages/grafana-data/src/types/panel.ts +++ b/packages/grafana-data/src/types/panel.ts @@ -156,7 +156,7 @@ export interface PanelOptionsEditorConfig boolean; + showIf?: (currentConfig: TOptions) => boolean | undefined; } /** diff --git a/packages/grafana-ui/src/components/Icon/Icon.tsx b/packages/grafana-ui/src/components/Icon/Icon.tsx index 9c21022bb30..2e707add34f 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.tsx +++ b/packages/grafana-ui/src/components/Icon/Icon.tsx @@ -88,7 +88,7 @@ export const getSvgSize = (size: IconSize) => { case 'lg': return 18; case 'xl': - return 28; + return 24; case 'xxl': return 36; case 'xxxl': diff --git a/packages/grafana-ui/src/components/Select/SelectMenu.tsx b/packages/grafana-ui/src/components/Select/SelectMenu.tsx index d131e78953e..92468032d5f 100644 --- a/packages/grafana-ui/src/components/Select/SelectMenu.tsx +++ b/packages/grafana-ui/src/components/Select/SelectMenu.tsx @@ -42,6 +42,7 @@ export const SelectMenuOptions = React.forwardRef [ diff --git a/public/app/core/components/TagFilter/TagFilter.tsx b/public/app/core/components/TagFilter/TagFilter.tsx index a3278cb59cd..c00d8b5596e 100644 --- a/public/app/core/components/TagFilter/TagFilter.tsx +++ b/public/app/core/components/TagFilter/TagFilter.tsx @@ -4,7 +4,7 @@ import { css } from 'emotion'; // @ts-ignore import { components } from '@torkelo/react-select'; import { AsyncSelect, stylesFactory } from '@grafana/ui'; -import { resetSelectStyles, Icon } from '@grafana/ui'; +import { Icon } from '@grafana/ui'; import { escapeStringForRegex } from '@grafana/data'; // Components import { TagOption } from './TagOption'; @@ -74,7 +74,6 @@ export class TagFilter extends React.Component { noOptionsMessage: 'No tags found', onChange: this.onChange, placeholder, - styles: resetSelectStyles(), value: tags, width, components: { diff --git a/public/app/core/components/sidemenu/TopSection.tsx b/public/app/core/components/sidemenu/TopSection.tsx index 827b868ea67..9820d92afec 100644 --- a/public/app/core/components/sidemenu/TopSection.tsx +++ b/public/app/core/components/sidemenu/TopSection.tsx @@ -2,13 +2,23 @@ import React, { FC } from 'react'; import _ from 'lodash'; import TopSectionItem from './TopSectionItem'; import config from '../../config'; +import { getLocationSrv } from '@grafana/runtime'; const TopSection: FC = () => { const navTree = _.cloneDeep(config.bootData.navTree); const mainLinks = _.filter(navTree, item => !item.hideFromMenu); + const searchLink = { + text: 'Search', + icon: 'search', + }; + + const onOpenSearch = () => { + getLocationSrv().update({ query: { search: 'open' }, partial: true }); + }; return (
+ {mainLinks.map((link, index) => { return ; })} diff --git a/public/app/core/components/sidemenu/TopSectionItem.test.tsx b/public/app/core/components/sidemenu/TopSectionItem.test.tsx index e7d3c4b7c75..1d014159caf 100644 --- a/public/app/core/components/sidemenu/TopSectionItem.test.tsx +++ b/public/app/core/components/sidemenu/TopSectionItem.test.tsx @@ -1,22 +1,24 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { mount } from 'enzyme'; import TopSectionItem from './TopSectionItem'; const setup = (propOverrides?: object) => { const props = Object.assign( { - link: {}, + link: { + text: 'Hello', + url: '/asd', + }, }, propOverrides ); - return shallow(); + return mount(); }; describe('Render', () => { it('should render component', () => { const wrapper = setup(); - expect(wrapper).toMatchSnapshot(); }); }); diff --git a/public/app/core/components/sidemenu/TopSectionItem.tsx b/public/app/core/components/sidemenu/TopSectionItem.tsx index e9b3649b873..1a095047273 100644 --- a/public/app/core/components/sidemenu/TopSectionItem.tsx +++ b/public/app/core/components/sidemenu/TopSectionItem.tsx @@ -1,18 +1,21 @@ import React, { FC } from 'react'; import SideMenuDropDown from './SideMenuDropDown'; import { Icon } from '@grafana/ui'; +import { NavModelItem } from '@grafana/data'; export interface Props { - link: any; + link: NavModelItem; + onClick?: () => void; } const TopSectionItem: FC = props => { - const { link } = props; + const { link, onClick } = props; + return (
- + - + {link.img && } diff --git a/public/app/core/components/sidemenu/__snapshots__/TopSection.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/TopSection.test.tsx.snap index c78ec726302..374763031a5 100644 --- a/public/app/core/components/sidemenu/__snapshots__/TopSection.test.tsx.snap +++ b/public/app/core/components/sidemenu/__snapshots__/TopSection.test.tsx.snap @@ -4,6 +4,15 @@ exports[`Render should render component 1`] = `
+ + - - - - - - -
+ + +
+ + + + + + +
+ `; diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index 3e63ebe1cf1..a764e366652 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -58,13 +58,6 @@ class DashNav extends PureComponent { this.playlistSrv = this.props.$injector.get('playlistSrv'); } - onDashboardNameClick = () => { - this.props.updateLocation({ - query: { search: 'open' }, - partial: true, - }); - }; - onFolderNameClick = () => { this.props.updateLocation({ query: { search: 'open', folder: 'current' }, @@ -169,13 +162,12 @@ class DashNav extends PureComponent { renderDashboardTitleSearchButton() { const { dashboard, isFullscreen } = this.props; - /* Hard-coded value so we don't have to wrap whole component in withTheme because of 1 variable */ - const iconClassName = css` - margin-right: 4px; - margin-bottom: -1px; + + const folderSymbol = css` + margin-right: 0 4px; `; const mainIconClassName = css` - margin-right: 4px; + margin-right: 8px; margin-bottom: 3px; `; @@ -190,14 +182,11 @@ class DashNav extends PureComponent { {haveFolder && ( <> - {folderTitle} + {folderTitle} / - )} - - {dashboard.title} - + {dashboard.title}
{this.renderLeftActionsButton()}
diff --git a/public/app/plugins/datasource/jaeger/datasource.test.ts b/public/app/plugins/datasource/jaeger/datasource.test.ts index 6d47bbeeb0c..c79217e6def 100644 --- a/public/app/plugins/datasource/jaeger/datasource.test.ts +++ b/public/app/plugins/datasource/jaeger/datasource.test.ts @@ -1,5 +1,5 @@ import { JaegerDatasource, JaegerQuery } from './datasource'; -import { DataQueryRequest, DataSourceInstanceSettings, FieldType, PluginType } from '@grafana/data'; +import { DataQueryRequest, DataSourceInstanceSettings, FieldType, PluginType, dateTime } from '@grafana/data'; import { BackendSrv, BackendSrvRequest, getBackendSrv, setBackendSrv } from '@grafana/runtime'; describe('JaegerDatasource', () => { @@ -77,7 +77,12 @@ const defaultQuery: DataQueryRequest = { interval: '0', panelId: 0, scopedVars: {}, - timezone: '', + range: { + from: dateTime().subtract(1, 'h'), + to: dateTime(), + raw: { from: '1h', to: 'now' }, + }, + timezone: 'browser', app: 'explore', startTime: 0, targets: [ diff --git a/public/app/plugins/panel/news/module.tsx b/public/app/plugins/panel/news/module.tsx index dc9a989adb5..ff42a3c4792 100755 --- a/public/app/plugins/panel/news/module.tsx +++ b/public/app/plugins/panel/news/module.tsx @@ -17,7 +17,7 @@ export const plugin = new PanelPlugin(NewsPanel).setPanelOptions(bu path: 'useProxy', name: 'Use Proxy', description: 'If the feed is unable to connect, consider a CORS proxy', - showIf: currentConfig => { + showIf: (currentConfig: NewsOptions) => { return currentConfig.feedUrl && !currentConfig.feedUrl.startsWith(PROXY_PREFIX); }, }); diff --git a/public/app/plugins/panel/stat/types.ts b/public/app/plugins/panel/stat/types.ts index 2f8f54742b2..9dab54eeb04 100644 --- a/public/app/plugins/panel/stat/types.ts +++ b/public/app/plugins/panel/stat/types.ts @@ -51,7 +51,7 @@ export function addStandardDataReduceOptions( min: 1, max: 5000, }, - showIf: options => options.reduceOptions.values, + showIf: options => options.reduceOptions.values === true, }); builder.addCustomEditor({ diff --git a/public/app/routes/routes.ts b/public/app/routes/routes.ts index 0ac68b8c369..c52253dc1b6 100644 --- a/public/app/routes/routes.ts +++ b/public/app/routes/routes.ts @@ -108,6 +108,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/dashboard/import', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -117,6 +118,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/datasources', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -138,6 +140,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/datasources/edit/:id/dashboards', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -147,6 +150,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/datasources/new', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -166,6 +170,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/dashboards/folder/new', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -175,6 +180,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/dashboards/f/:uid/:slug/permissions', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -184,6 +190,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/dashboards/f/:uid/:slug/settings', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -231,6 +238,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/org', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "OrgDetailsPage" */ '../features/org/OrgDetailsPage')), @@ -238,12 +246,14 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/org/new', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "NewOrgPage" */ 'app/features/org/NewOrgPage')), }, }) .when('/org/users', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "UsersListPage" */ 'app/features/users/UsersListPage')), @@ -251,6 +261,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/org/users/invite', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "UserInvitePage" */ 'app/features/org/UserInvitePage')), @@ -258,6 +269,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/org/apikeys', { template: '', + reloadOnSearch: false, resolve: { roles: () => ['Editor', 'Admin'], component: () => @@ -266,6 +278,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/org/teams', { template: '', + reloadOnSearch: false, resolve: { roles: () => (config.editorsCanAdmin ? [] : ['Editor', 'Admin']), component: () => SafeDynamicImport(import(/* webpackChunkName: "TeamList" */ 'app/features/teams/TeamList')), @@ -273,6 +286,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/org/teams/new', { template: '', + reloadOnSearch: false, resolve: { roles: () => (config.editorsCanAdmin ? [] : ['Admin']), component: () => @@ -281,6 +295,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/org/teams/edit/:id/:page?', { template: '', + reloadOnSearch: false, resolve: { roles: () => (config.editorsCanAdmin ? [] : ['Admin']), component: () => SafeDynamicImport(import(/* webpackChunkName: "TeamPages" */ 'app/features/teams/TeamPages')), @@ -290,9 +305,11 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati templateUrl: 'public/app/features/profile/partials/profile.html', controller: 'ProfileCtrl', controllerAs: 'ctrl', + reloadOnSearch: false, }) .when('/profile/password', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -303,15 +320,18 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati .when('/profile/select-org', { templateUrl: 'public/app/features/org/partials/select_org.html', controller: 'SelectOrgCtrl', + reloadOnSearch: false, }) // ADMIN .when('/admin', { templateUrl: 'public/app/features/admin/partials/admin_home.html', controller: 'AdminHomeCtrl', controllerAs: 'ctrl', + reloadOnSearch: false, }) .when('/admin/settings', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "AdminSettings" */ 'app/features/admin/AdminSettings')), @@ -319,12 +339,14 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/admin/upgrading', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import('app/features/admin/UpgradePage')), }, }) .when('/admin/users', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "UserListAdminPage" */ 'app/features/admin/UserListAdminPage')), @@ -332,6 +354,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/admin/users/create', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "UserCreatePage" */ 'app/features/admin/UserCreatePage')), @@ -339,12 +362,14 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/admin/users/edit/:id', { template: '', + reloadOnSearch: false, resolve: { component: () => UserAdminPage, }, }) .when('/admin/orgs', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "AdminListOrgsPage" */ 'app/features/admin/AdminListOrgsPage')), @@ -352,6 +377,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/admin/orgs/edit/:id', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "AdminEditOrgPage" */ 'app/features/admin/AdminEditOrgPage')), @@ -359,6 +385,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/admin/stats', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "ServerStats" */ 'app/features/admin/ServerStats')), @@ -366,6 +393,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/admin/ldap', { template: '', + reloadOnSearch: false, resolve: { component: () => LdapPage, }, @@ -410,6 +438,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/plugins', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "PluginListPage" */ 'app/features/plugins/PluginListPage')), @@ -417,7 +446,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/plugins/:pluginId/', { template: '', - reloadOnSearch: false, // tabs from query parameters + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport(import(/* webpackChunkName: "PluginPage" */ '../features/plugins/PluginPage')), @@ -427,6 +456,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati templateUrl: 'public/app/features/plugins/partials/plugin_page.html', controller: 'AppPageCtrl', controllerAs: 'ctrl', + reloadOnSearch: false, }) .when('/alerting', { redirectTo: '/alerting/list', @@ -441,6 +471,7 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati }) .when('/alerting/notifications', { template: '', + reloadOnSearch: false, resolve: { component: () => SafeDynamicImport( @@ -452,15 +483,18 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati templateUrl: 'public/app/features/alerting/partials/notification_edit.html', controller: 'AlertNotificationEditCtrl', controllerAs: 'ctrl', + reloadOnSearch: false, }) .when('/alerting/notification/:id/edit', { templateUrl: 'public/app/features/alerting/partials/notification_edit.html', controller: 'AlertNotificationEditCtrl', controllerAs: 'ctrl', + reloadOnSearch: false, }) .otherwise({ templateUrl: 'public/app/partials/error.html', controller: 'ErrorCtrl', + reloadOnSearch: false, }); applyRouteRegistrationHandlers($routeProvider); diff --git a/public/sass/components/_navbar.scss b/public/sass/components/_navbar.scss index d4e5b09761e..b7c5efcbcf9 100644 --- a/public/sass/components/_navbar.scss +++ b/public/sass/components/_navbar.scss @@ -76,7 +76,7 @@ .navbar-page-btn__folder { display: none; - padding-right: 8px; + padding-right: 4px; @include media-breakpoint-up(lg) { display: inline-block; diff --git a/scripts/ci-frontend-metrics.sh b/scripts/ci-frontend-metrics.sh index 27a5e09061e..b64406f1042 100755 --- a/scripts/ci-frontend-metrics.sh +++ b/scripts/ci-frontend-metrics.sh @@ -4,7 +4,7 @@ echo -e "Collecting code stats (typescript errors & more)" -ERROR_COUNT_LIMIT=788 +ERROR_COUNT_LIMIT=771 DIRECTIVES_LIMIT=172 CONTROLLERS_LIMIT=139