From 4484a14b205159c38c9435f6cc845ef6c20f100c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 28 Jun 2022 17:19:55 +0200 Subject: [PATCH 01/14] First stab at new page layouts behind feature toggle --- .betterer.results | 34 ++-- .../src/components/Tabs/VerticalTabs.tsx | 104 ++++++++++++ packages/grafana-ui/src/components/index.ts | 1 + .../core/components/ErrorPage/ErrorPage.tsx | 2 +- public/app/core/components/Page/Page.tsx | 12 +- .../core/components/PageLayouts/NewPage.tsx | 152 ++++++++++++++++++ .../components/PageLayouts/PageContents.tsx | 14 ++ .../components/PageLayouts/SectionNav.tsx | 91 +++++++++++ .../app/core/components/TopNav/TopNavPage.tsx | 4 +- .../app/features/admin/AdminEditOrgPage.tsx | 2 +- .../app/features/admin/AdminListOrgsPage.tsx | 2 +- public/app/features/admin/AdminSettings.tsx | 2 +- public/app/features/admin/UpgradePage.tsx | 2 +- public/app/features/admin/UserAdminPage.tsx | 2 +- public/app/features/admin/UserCreatePage.tsx | 2 +- .../app/features/admin/UserListAdminPage.tsx | 2 +- public/app/features/admin/ldap/LdapPage.tsx | 2 +- .../app/features/alerting/AlertRuleList.tsx | 2 +- .../alerting/EditNotificationChannelPage.tsx | 2 +- .../features/alerting/FeatureTogglePage.tsx | 2 +- .../alerting/NewNotificationChannelPage.tsx | 2 +- .../alerting/NotificationsListPage.tsx | 2 +- .../features/alerting/unified/RuleEditor.tsx | 2 +- .../components/AlertingPageWrapper.tsx | 2 +- public/app/features/api-keys/ApiKeysPage.tsx | 2 +- .../dashboard/containers/DashboardPage.tsx | 5 +- .../datasources/DataSourceDashboards.tsx | 2 +- .../datasources/DataSourcesListPage.tsx | 2 +- .../datasources/NewDataSourcePage.tsx | 2 +- .../settings/DataSourceSettingsPage.tsx | 2 +- .../features/explore/FeatureTogglePage.tsx | 2 +- .../AccessControlFolderPermissions.tsx | 2 +- .../app/features/folders/FolderAlerting.tsx | 2 +- .../folders/FolderLibraryPanelsPage.tsx | 3 +- .../features/folders/FolderPermissions.tsx | 2 +- .../features/folders/FolderSettingsPage.tsx | 2 +- .../components/NewDashboardsFolder.tsx | 2 +- public/app/features/invites/SignupInvited.tsx | 2 +- .../library-panels/LibraryPanelsPage.tsx | 3 +- .../features/live/pages/CloudAdminPage.tsx | 2 +- .../features/live/pages/FeatureTogglePage.tsx | 2 +- .../features/live/pages/LiveStatusPage.tsx | 2 +- .../features/live/pages/PipelineAdminPage.tsx | 2 +- .../manage-dashboards/DashboardImportPage.tsx | 2 +- .../manage-dashboards/SnapshotListPage.tsx | 2 +- .../notifications/NotificationsPage.tsx | 3 +- public/app/features/org/NewOrgPage.tsx | 2 +- public/app/features/org/OrgDetailsPage.tsx | 2 +- public/app/features/org/SelectOrgPage.tsx | 2 +- public/app/features/org/UserInvitePage.tsx | 2 +- .../features/playlist/PlaylistEditPage.tsx | 2 +- .../app/features/playlist/PlaylistNewPage.tsx | 2 +- public/app/features/playlist/PlaylistPage.tsx | 2 +- .../plugins/components/AppPluginLoader.tsx | 2 +- .../plugins/components/AppRootPage.tsx | 2 +- .../features/profile/ChangePasswordPage.tsx | 2 +- .../features/profile/FeatureTogglePage.tsx | 2 +- .../features/profile/UserProfileEditPage.tsx | 2 +- public/app/features/sandbox/TestStuffPage.tsx | 2 +- .../search/components/DashboardListPage.tsx | 2 +- .../ServiceAccountCreatePage.tsx | 2 +- .../serviceaccounts/ServiceAccountPage.tsx | 2 +- .../ServiceAccountsListPage.tsx | 2 +- public/app/features/teams/CreateTeam.tsx | 2 +- public/app/features/teams/TeamList.tsx | 2 +- public/app/features/teams/TeamPages.tsx | 2 +- public/app/features/users/UsersListPage.tsx | 2 +- 67 files changed, 455 insertions(+), 81 deletions(-) create mode 100644 packages/grafana-ui/src/components/Tabs/VerticalTabs.tsx create mode 100644 public/app/core/components/PageLayouts/NewPage.tsx create mode 100644 public/app/core/components/PageLayouts/PageContents.tsx create mode 100644 public/app/core/components/PageLayouts/SectionNav.tsx diff --git a/.betterer.results b/.betterer.results index e4534e05a0b1a..54302bef83179 100644 --- a/.betterer.results +++ b/.betterer.results @@ -3347,6 +3347,12 @@ exports[`better eslint`] = { [65, 22, 22, "Do not use any type assertions.", "4054086100"], [104, 34, 21, "Do not use any type assertions.", "2401004021"] ], + "public/app/core/components/PageLayouts/NewPage.tsx:4153212563": [ + [66, 34, 22, "Do not use any type assertions.", "4054086100"] + ], + "public/app/core/components/PageLayouts/SectionNav.tsx:1750474659": [ + [20, 34, 21, "Do not use any type assertions.", "2401004021"] + ], "public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx:1614517181": [ [41, 24, 3, "Unexpected any. Specify a different type.", "193409811"], [42, 24, 3, "Unexpected any. Specify a different type.", "193409811"] @@ -3965,23 +3971,23 @@ exports[`better eslint`] = { [26, 5, 29, "Do not use any type assertions.", "2635161824"], [67, 9, 60, "Do not use any type assertions.", "738572730"] ], - "public/app/features/admin/AdminListOrgsPage.tsx:1232501301": [ + "public/app/features/admin/AdminListOrgsPage.tsx:851621779": [ [22, 32, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/admin/AdminSettings.tsx:876474391": [ + "public/app/features/admin/AdminSettings.tsx:3612709745": [ [18, 10, 63, "Do not use any type assertions.", "1950730127"] ], "public/app/features/admin/OrgRolePicker.tsx:2826049686": [ [23, 34, 20, "Do not use any type assertions.", "3568020359"] ], - "public/app/features/admin/UserListAdminPage.tsx:3454473979": [ + "public/app/features/admin/UserListAdminPage.tsx:1874540957": [ [27, 21, 3, "Unexpected any. Specify a different type.", "193409811"] ], "public/app/features/admin/UserProfile.tsx:2121737967": [ [205, 24, 3, "Unexpected any. Specify a different type.", "193409811"], [302, 10, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/admin/ldap/LdapPage.tsx:1724804732": [ + "public/app/features/admin/ldap/LdapPage.tsx:2036572570": [ [73, 19, 3, "Unexpected any. Specify a different type.", "193409811"] ], "public/app/features/admin/state/reducers.test.ts:3463255684": [ @@ -4000,7 +4006,7 @@ exports[`better eslint`] = { [57, 34, 39, "Do not use any type assertions.", "935682756"], [57, 70, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/alerting/AlertRuleList.tsx:474918126": [ + "public/app/features/alerting/AlertRuleList.tsx:3637063496": [ [134, 24, 17, "Do not use any type assertions.", "2518695225"], [137, 58, 17, "Do not use any type assertions.", "2518695225"] ], @@ -4050,7 +4056,7 @@ exports[`better eslint`] = { [402, 51, 3, "Unexpected any. Specify a different type.", "193409811"], [468, 34, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/alerting/EditNotificationChannelPage.tsx:3397946803": [ + "public/app/features/alerting/EditNotificationChannelPage.tsx:3335986965": [ [21, 23, 3, "Unexpected any. Specify a different type.", "193409811"] ], "public/app/features/alerting/StateHistory.tsx:3418297987": [ @@ -5022,7 +5028,7 @@ exports[`better eslint`] = { [264, 15, 56, "Do not use any type assertions.", "2674630592"], [266, 13, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/dashboard/containers/DashboardPage.tsx:3173260528": [ + "public/app/features/dashboard/containers/DashboardPage.tsx:3380941351": [ [108, 36, 40, "Do not use any type assertions.", "2547843745"], [108, 73, 3, "Unexpected any. Specify a different type.", "193409811"], [144, 32, 40, "Do not use any type assertions.", "2547843745"], @@ -5446,14 +5452,14 @@ exports[`better eslint`] = { [15, 16, 24, "Do not use any type assertions.", "3405802617"], [21, 11, 21, "Do not use any type assertions.", "3218407483"] ], - "public/app/features/datasources/DataSourceDashboards.tsx:3932611556": [ + "public/app/features/datasources/DataSourceDashboards.tsx:2085374850": [ [49, 16, 3, "Unexpected any. Specify a different type.", "193409811"] ], "public/app/features/datasources/DataSourcesListPage.test.tsx:368182366": [ [19, 17, 26, "Do not use any type assertions.", "3994646623"], [22, 14, 126, "Do not use any type assertions.", "1409469672"] ], - "public/app/features/datasources/DataSourcesListPage.tsx:247845505": [ + "public/app/features/datasources/DataSourcesListPage.tsx:2606271463": [ [44, 14, 22, "Do not use any type assertions.", "2167463294"] ], "public/app/features/datasources/__mocks__/dataSourcesMocks.ts:1217473343": [ @@ -6162,7 +6168,7 @@ exports[`better eslint`] = { "public/app/features/live/pages/AddNewRule.tsx:2593231672": [ [59, 16, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/live/pages/PipelineAdminPage.tsx:952820098": [ + "public/app/features/live/pages/PipelineAdminPage.tsx:87558436": [ [13, 51, 3, "Unexpected any. Specify a different type.", "193409811"] ], "public/app/features/live/pages/PipelineTable.tsx:894975337": [ @@ -6189,7 +6195,7 @@ exports[`better eslint`] = { "public/app/features/live/pages/utils.ts:270086979": [ [19, 37, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/manage-dashboards/DashboardImportPage.tsx:1780804260": [ + "public/app/features/manage-dashboards/DashboardImportPage.tsx:1590008002": [ [81, 19, 3, "Unexpected any. Specify a different type.", "193409811"], [82, 25, 3, "Unexpected any. Specify a different type.", "193409811"] ], @@ -6490,7 +6496,7 @@ exports[`better eslint`] = { [68, 90, 12, "Do not use any type assertions.", "3603862904"], [68, 99, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/plugins/components/AppRootPage.tsx:1453161637": [ + "public/app/features/plugins/components/AppRootPage.tsx:3831200387": [ [109, 21, 34, "Do not use any type assertions.", "462520373"] ], "public/app/features/plugins/datasource_srv.ts:3002426838": [ @@ -6771,7 +6777,7 @@ exports[`better eslint`] = { [12, 13, 3, "Unexpected any. Specify a different type.", "193409811"], [41, 9, 43, "Do not use any type assertions.", "4109129169"] ], - "public/app/features/sandbox/TestStuffPage.tsx:3698683147": [ + "public/app/features/sandbox/TestStuffPage.tsx:1930871651": [ [134, 30, 29, "Do not use any type assertions.", "3195381622"] ], "public/app/features/search/components/DashboardSearch.test.tsx:3245889886": [ @@ -6979,7 +6985,7 @@ exports[`better eslint`] = { [79, 18, 88, "Do not use any type assertions.", "2247670218"], [138, 20, 95, "Do not use any type assertions.", "4068964415"] ], - "public/app/features/teams/TeamPages.tsx:3881385980": [ + "public/app/features/teams/TeamPages.tsx:2748675066": [ [52, 43, 18, "Do not use any type assertions.", "373851894"] ], "public/app/features/teams/state/reducers.ts:1856799550": [ diff --git a/packages/grafana-ui/src/components/Tabs/VerticalTabs.tsx b/packages/grafana-ui/src/components/Tabs/VerticalTabs.tsx new file mode 100644 index 0000000000000..4e40ba0f8095e --- /dev/null +++ b/packages/grafana-ui/src/components/Tabs/VerticalTabs.tsx @@ -0,0 +1,104 @@ +import { css, cx } from '@emotion/css'; +import React, { HTMLProps } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { useStyles2 } from '../../themes/ThemeContext'; +import { IconName } from '../../types'; +import { Icon } from '../Icon/Icon'; + +import { Counter } from './Counter'; + +export interface TabProps extends HTMLProps { + label: string; + active?: boolean; + /** When provided, it is possible to use the tab as a hyperlink. Use in cases where the tabs update location. */ + href?: string; + icon?: IconName; + /** A number rendered next to the text. Usually used to display the number of items in a tab's view. */ + counter?: number | null; +} + +export const VerticalTab = React.forwardRef( + ({ label, active, icon, counter, className, href, ...otherProps }, ref) => { + const tabsStyles = useStyles2(getTabStyles); + const content = () => ( + <> + {icon && } + {label} + {typeof counter === 'number' && } + + ); + + return ( +
  • + {href ? ( + + {content()} + + ) : ( + <>{content()} + )} +
  • + ); + } +); + +VerticalTab.displayName = 'Tab'; + +const getTabStyles = (theme: GrafanaTheme2) => { + return { + tabItem: css` + list-style: none; + margin-right: ${theme.spacing(2)}; + position: relative; + display: block; + color: ${theme.colors.text.primary}; + cursor: pointer; + margin-bottom: 4px; + + svg { + margin-right: ${theme.spacing(1)}; + } + + a { + display: block; + height: 100%; + } + + &:hover, + &:focus { + a { + text-decoration: underline; + } + } + `, + padding: css` + padding: 6px 12px; + `, + activeStyle: css` + label: activeTabStyle; + color: ${theme.colors.text.maxContrast}; + font-weight: 500; + overflow: hidden; + + &::before { + display: block; + content: ' '; + position: absolute; + left: 0; + width: 4px; + bottom: 0; + top: 0; + border-radius: 2px; + background-image: linear-gradient(0deg, #f05a28 30%, #fbca0a 99%); + } + `, + }; +}; diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index 721d749c863c5..8d6ae3736b96c 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -79,6 +79,7 @@ export { TableCellDisplayMode, TableSortByFieldState } from './Table/types'; export { TableInputCSV } from './TableInputCSV/TableInputCSV'; export { TabsBar } from './Tabs/TabsBar'; export { Tab } from './Tabs/Tab'; +export { VerticalTab } from './Tabs/VerticalTabs'; export { TabContent } from './Tabs/TabContent'; export { Counter } from './Tabs/Counter'; diff --git a/public/app/core/components/ErrorPage/ErrorPage.tsx b/public/app/core/components/ErrorPage/ErrorPage.tsx index 8fe3e4c645ed9..25e77912f6c44 100644 --- a/public/app/core/components/ErrorPage/ErrorPage.tsx +++ b/public/app/core/components/ErrorPage/ErrorPage.tsx @@ -7,7 +7,7 @@ import { Icon } from '@grafana/ui'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; -import Page from '../Page/Page'; +import { Page } from '../Page/Page'; interface ConnectedProps { navModel: NavModel; diff --git a/public/app/core/components/Page/Page.tsx b/public/app/core/components/Page/Page.tsx index 121b9ba1548c5..806145f642bc1 100644 --- a/public/app/core/components/Page/Page.tsx +++ b/public/app/core/components/Page/Page.tsx @@ -3,6 +3,7 @@ import { css, cx } from '@emotion/css'; import React, { FC, HTMLAttributes, useEffect } from 'react'; import { GrafanaTheme2, NavModel } from '@grafana/data'; +import { config } from '@grafana/runtime'; import { CustomScrollbar, useStyles2 } from '@grafana/ui'; import { getTitleFromNavModel } from 'app/core/selectors/navModel'; @@ -10,6 +11,7 @@ import { getTitleFromNavModel } from 'app/core/selectors/navModel'; import { Branding } from '../Branding/Branding'; import { Footer } from '../Footer/Footer'; import PageHeader from '../PageHeader/PageHeader'; +import { NewPage } from '../PageLayouts/NewPage'; import { PageContents } from './PageContents'; @@ -23,7 +25,7 @@ export interface PageType extends FC { Contents: typeof PageContents; } -export const Page: PageType = ({ navModel, children, className, ...otherProps }) => { +export const OldPage: PageType = ({ navModel, children, className, ...otherProps }) => { const styles = useStyles2(getStyles); useEffect(() => { @@ -48,12 +50,12 @@ export const Page: PageType = ({ navModel, children, className, ...otherProps }) ); }; -Page.Header = PageHeader; -Page.Contents = PageContents; +OldPage.Header = PageHeader; +OldPage.Contents = PageContents; -export default Page; +export const Page: PageType = config.featureToggles.topnav ? NewPage : OldPage; -const getStyles = (theme: GrafanaTheme2) => ({ +const getStyles = (_: GrafanaTheme2) => ({ wrapper: css` width: 100%; flex-grow: 1; diff --git a/public/app/core/components/PageLayouts/NewPage.tsx b/public/app/core/components/PageLayouts/NewPage.tsx new file mode 100644 index 0000000000000..624af2eceddab --- /dev/null +++ b/public/app/core/components/PageLayouts/NewPage.tsx @@ -0,0 +1,152 @@ +// Libraries +import { css, cx } from '@emotion/css'; +import React, { HTMLAttributes, useEffect, FC } from 'react'; + +import { GrafanaTheme2, NavModel } from '@grafana/data'; +import { CustomScrollbar, IconName, Tab, TabsBar, useStyles2 } from '@grafana/ui'; +import { getTitleFromNavModel } from 'app/core/selectors/navModel'; + +// Components +import { Branding } from '../Branding/Branding'; +import { Footer } from '../Footer/Footer'; +import PageHeader from '../PageHeader/PageHeader'; + +import { PageContents } from './PageContents'; +import { SectionNav } from './SectionNav'; + +interface Props extends HTMLAttributes { + children: React.ReactNode; + navModel?: NavModel; +} + +export interface PageType extends FC { + Header: typeof PageHeader; + Contents: typeof PageContents; +} + +export const NewPage: PageType = ({ navModel, children, className, ...otherProps }: Props) => { + const styles = useStyles2(getStyles); + + useEffect(() => { + if (navModel) { + const title = getTitleFromNavModel(navModel); + document.title = title ? `${title} - ${Branding.AppTitle}` : Branding.AppTitle; + } else { + document.title = Branding.AppTitle; + } + }, [navModel]); + + if (!navModel) { + return null; + } + + return ( +
    +
    + {navModel.main.children && } +
    + +
    +

    + {navModel.node.img && ( + {`logo + )} + {navModel.node.text} +

    + {navModel.node.subTitle &&
    {navModel.node.subTitle}
    } + {navModel.node.children && ( + <> + + {navModel.node.children.map((child, index) => { + return ( + !child.hideFromTabs && ( + + ) + ); + })} + +
    {children}
    + + )} + {!navModel.node.children && children} +
    +
    + +
    +
    +
    + ); +}; + +NewPage.Header = PageHeader; +NewPage.Contents = PageContents; + +const getStyles = (theme: GrafanaTheme2) => { + const style1 = window.location.href.indexOf('style=1') > -1; + const margin = style1 ? theme.spacing(1, 1, 0, 1) : theme.spacing(2, 2, 2, 1); + const border = style1 ? `1px solid ${theme.colors.border.weak}` : 'none'; + + const shadow = theme.isDark + ? `0 0.6px 1.5px -1px rgb(0 0 0),0 2px 4px -1px rgb(0 0 0 / 40%),0 5px 10px -1px rgb(0 0 0 / 23%)` + : '0 0.6px 1.5px -1px rgb(0 0 0 / 8%),0 2px 4px rgb(0 0 0 / 6%),0 5px 10px -1px rgb(0 0 0 / 5%)'; + + return { + wrapper: css` + height: 100%; + display: flex; + flex: 1 1 0; + flex-direction: column; + min-height: 0; + `, + panes: css({ + display: 'flex', + height: '100%', + width: '100%', + flexGrow: 1, + minHeight: 0, + flexDirection: 'column', + [theme.breakpoints.up('md')]: { + flexDirection: 'row', + }, + }), + pageTitle: css({ + display: 'flex', + marginBottom: theme.spacing(3), + }), + pageSubTitle: css({ + marginBottom: theme.spacing(2), + position: 'relative', + top: theme.spacing(-1), + color: theme.colors.text.secondary, + }), + pageImg: css({ + width: '32px', + height: '32px', + marginRight: theme.spacing(2), + }), + pageContent: css({ + flexGrow: 1, + }), + pageInner: css({ + padding: theme.spacing(3), + boxShadow: shadow, + background: theme.colors.background.primary, + margin: margin, + border: border, + display: 'flex', + flexDirection: 'column', + flexGrow: 1, + }), + tabContent: css({ + paddingTop: theme.spacing(3), + flexGrow: 1, + }), + }; +}; diff --git a/public/app/core/components/PageLayouts/PageContents.tsx b/public/app/core/components/PageLayouts/PageContents.tsx new file mode 100644 index 0000000000000..85a04fa295aa6 --- /dev/null +++ b/public/app/core/components/PageLayouts/PageContents.tsx @@ -0,0 +1,14 @@ +// Libraries +import React, { FC } from 'react'; + +import PageLoader from '../PageLoader/PageLoader'; + +interface Props { + isLoading?: boolean; + children: React.ReactNode; + className?: string; +} + +export const PageContents: FC = ({ isLoading, children }) => { + return <>{isLoading ? : children}; +}; diff --git a/public/app/core/components/PageLayouts/SectionNav.tsx b/public/app/core/components/PageLayouts/SectionNav.tsx new file mode 100644 index 0000000000000..0f8110e2beffe --- /dev/null +++ b/public/app/core/components/PageLayouts/SectionNav.tsx @@ -0,0 +1,91 @@ +import { css } from '@emotion/css'; +import React from 'react'; + +import { NavModel, GrafanaTheme2 } from '@grafana/data'; +import { IconName, useStyles2, Icon, VerticalTab } from '@grafana/ui'; + +export interface Props { + model: NavModel; +} + +export function SectionNav(props: Props) { + const styles = useStyles2(getStyles); + + const main = props.model.main; + const directChildren = props.model.main.children!.filter((x) => !x.hideFromTabs && !x.children); + const nestedItems = props.model.main.children!.filter((x) => x.children && x.children.length); + + return ( + + ); +} + +const getStyles = (theme: GrafanaTheme2) => { + return { + nav: css({ + display: 'flex', + flexDirection: 'column', + background: theme.colors.background.canvas, + padding: theme.spacing(3, 2), + [theme.breakpoints.up('md')]: { + width: '250px', + }, + }), + sectionName: css({ + display: 'flex', + gap: theme.spacing(1), + padding: theme.spacing(0.5, 0, 3, 0.25), + fontSize: theme.typography.h4.fontSize, + margin: 0, + }), + items: css({ + // paddingLeft: '9px', + }), + subSection: css({ + padding: theme.spacing(3, 0, 1, 1), + fontWeight: 500, + fontSize: '16px', + }), + }; +}; diff --git a/public/app/core/components/TopNav/TopNavPage.tsx b/public/app/core/components/TopNav/TopNavPage.tsx index 5924ad6948522..de7153a615c78 100644 --- a/public/app/core/components/TopNav/TopNavPage.tsx +++ b/public/app/core/components/TopNav/TopNavPage.tsx @@ -60,11 +60,11 @@ const getStyles = (theme: GrafanaTheme2) => { }), content: css({ display: 'flex', - paddingTop: TOP_BAR_LEVEL_HEIGHT * 2 + 16, + paddingTop: TOP_BAR_LEVEL_HEIGHT * 2, flexGrow: 1, }), contentNoSearchBar: css({ - paddingTop: TOP_BAR_LEVEL_HEIGHT + 16, + paddingTop: TOP_BAR_LEVEL_HEIGHT, }), topNav: css({ display: 'flex', diff --git a/public/app/features/admin/AdminEditOrgPage.tsx b/public/app/features/admin/AdminEditOrgPage.tsx index 44bc10e013409..8ab6d856d77c6 100644 --- a/public/app/features/admin/AdminEditOrgPage.tsx +++ b/public/app/features/admin/AdminEditOrgPage.tsx @@ -6,7 +6,7 @@ import { useAsyncFn } from 'react-use'; import { UrlQueryValue } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { Form, Field, Input, Button, Legend, Alert } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/admin/AdminListOrgsPage.tsx b/public/app/features/admin/AdminListOrgsPage.tsx index 6fff515aa0908..94757ff371569 100644 --- a/public/app/features/admin/AdminListOrgsPage.tsx +++ b/public/app/features/admin/AdminListOrgsPage.tsx @@ -4,7 +4,7 @@ import useAsyncFn from 'react-use/lib/useAsyncFn'; import { getBackendSrv } from '@grafana/runtime'; import { LinkButton } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { contextSrv } from 'app/core/services/context_srv'; import { AccessControlAction } from 'app/types'; diff --git a/public/app/features/admin/AdminSettings.tsx b/public/app/features/admin/AdminSettings.tsx index e2e2a0c7ecbf3..f0b90e6e2b8b3 100644 --- a/public/app/features/admin/AdminSettings.tsx +++ b/public/app/features/admin/AdminSettings.tsx @@ -4,7 +4,7 @@ import { useAsync } from 'react-use'; import { NavModel } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/admin/UpgradePage.tsx b/public/app/features/admin/UpgradePage.tsx index 3678cb244c633..07b93187d285e 100644 --- a/public/app/features/admin/UpgradePage.tsx +++ b/public/app/features/admin/UpgradePage.tsx @@ -4,8 +4,8 @@ import { connect } from 'react-redux'; import { GrafanaTheme2, NavModel } from '@grafana/data'; import { LinkButton, useStyles2 } from '@grafana/ui'; +import { Page } from 'app/core/components/Page/Page'; -import Page from '../../core/components/Page/Page'; import { getNavModel } from '../../core/selectors/navModel'; import { StoreState } from '../../types'; diff --git a/public/app/features/admin/UserAdminPage.tsx b/public/app/features/admin/UserAdminPage.tsx index 264e9ce943ae6..14865464d1e81 100644 --- a/public/app/features/admin/UserAdminPage.tsx +++ b/public/app/features/admin/UserAdminPage.tsx @@ -3,7 +3,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { NavModel } from '@grafana/data'; import { featureEnabled } from '@grafana/runtime'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/admin/UserCreatePage.tsx b/public/app/features/admin/UserCreatePage.tsx index b98e82a3e6a79..e68a20eeebf2f 100644 --- a/public/app/features/admin/UserCreatePage.tsx +++ b/public/app/features/admin/UserCreatePage.tsx @@ -5,7 +5,7 @@ import { useHistory } from 'react-router-dom'; import { NavModel } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { Form, Button, Input, Field } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from '../../core/selectors/navModel'; import { StoreState } from '../../types'; diff --git a/public/app/features/admin/UserListAdminPage.tsx b/public/app/features/admin/UserListAdminPage.tsx index 7fa5809ae4f37..f7435d397df21 100644 --- a/public/app/features/admin/UserListAdminPage.tsx +++ b/public/app/features/admin/UserListAdminPage.tsx @@ -13,7 +13,7 @@ import { useStyles2, FilterInput, } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; import { contextSrv } from 'app/core/core'; diff --git a/public/app/features/admin/ldap/LdapPage.tsx b/public/app/features/admin/ldap/LdapPage.tsx index 28adbdc13ad9b..f0959e6f70e89 100644 --- a/public/app/features/admin/ldap/LdapPage.tsx +++ b/public/app/features/admin/ldap/LdapPage.tsx @@ -5,7 +5,7 @@ import { NavModel } from '@grafana/data'; import { featureEnabled } from '@grafana/runtime'; import { Alert, Button, LegacyForms } from '@grafana/ui'; const { FormField } = LegacyForms; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/alerting/AlertRuleList.tsx b/public/app/features/alerting/AlertRuleList.tsx index 10de691e571f5..a19d2ab7bbd2b 100644 --- a/public/app/features/alerting/AlertRuleList.tsx +++ b/public/app/features/alerting/AlertRuleList.tsx @@ -5,7 +5,7 @@ import { SelectableValue } from '@grafana/data'; import { config, locationService } from '@grafana/runtime'; import { Button, FilterInput, LinkButton, Select, VerticalGroup } from '@grafana/ui'; import appEvents from 'app/core/app_events'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { AlertRule, StoreState } from 'app/types'; diff --git a/public/app/features/alerting/EditNotificationChannelPage.tsx b/public/app/features/alerting/EditNotificationChannelPage.tsx index 45aba248222ce..7303f7ccfd36e 100644 --- a/public/app/features/alerting/EditNotificationChannelPage.tsx +++ b/public/app/features/alerting/EditNotificationChannelPage.tsx @@ -4,7 +4,7 @@ import { MapDispatchToProps, MapStateToProps } from 'react-redux'; import { NavModel } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Form, Spinner } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { connectWithCleanUp } from 'app/core/components/connectWithCleanUp'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/alerting/FeatureTogglePage.tsx b/public/app/features/alerting/FeatureTogglePage.tsx index 63f62796f9403..e6def5ec3f581 100644 --- a/public/app/features/alerting/FeatureTogglePage.tsx +++ b/public/app/features/alerting/FeatureTogglePage.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; export default function FeatureTogglePage() { diff --git a/public/app/features/alerting/NewNotificationChannelPage.tsx b/public/app/features/alerting/NewNotificationChannelPage.tsx index 418029fb2e56b..93d6ca43865ce 100644 --- a/public/app/features/alerting/NewNotificationChannelPage.tsx +++ b/public/app/features/alerting/NewNotificationChannelPage.tsx @@ -3,7 +3,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { config } from '@grafana/runtime'; import { Form } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { NotificationChannelDTO, StoreState } from '../../types'; diff --git a/public/app/features/alerting/NotificationsListPage.tsx b/public/app/features/alerting/NotificationsListPage.tsx index 9a5e5b3f4eb08..6f11e260aac02 100644 --- a/public/app/features/alerting/NotificationsListPage.tsx +++ b/public/app/features/alerting/NotificationsListPage.tsx @@ -4,7 +4,7 @@ import { useAsyncFn } from 'react-use'; import { getBackendSrv } from '@grafana/runtime'; import { HorizontalGroup, Button, LinkButton } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { appEvents } from 'app/core/core'; import { useNavModel } from 'app/core/hooks/useNavModel'; import { AlertNotification } from 'app/types/alerting'; diff --git a/public/app/features/alerting/unified/RuleEditor.tsx b/public/app/features/alerting/unified/RuleEditor.tsx index 57d66fc319f4d..e550148abbea0 100644 --- a/public/app/features/alerting/unified/RuleEditor.tsx +++ b/public/app/features/alerting/unified/RuleEditor.tsx @@ -5,7 +5,7 @@ import { useAsync } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; import { Alert, LinkButton, LoadingPlaceholder, useStyles2, withErrorBoundary } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { useCleanup } from 'app/core/hooks/useCleanup'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { RuleIdentifier } from 'app/types/unified-alerting'; diff --git a/public/app/features/alerting/unified/components/AlertingPageWrapper.tsx b/public/app/features/alerting/unified/components/AlertingPageWrapper.tsx index 21a7826139e90..bb87e4a7a4ead 100644 --- a/public/app/features/alerting/unified/components/AlertingPageWrapper.tsx +++ b/public/app/features/alerting/unified/components/AlertingPageWrapper.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import { useSelector } from 'react-redux'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types/store'; diff --git a/public/app/features/api-keys/ApiKeysPage.tsx b/public/app/features/api-keys/ApiKeysPage.tsx index 9df08efd22e25..4cb20857620c3 100644 --- a/public/app/features/api-keys/ApiKeysPage.tsx +++ b/public/app/features/api-keys/ApiKeysPage.tsx @@ -6,7 +6,7 @@ import { rangeUtil } from '@grafana/data'; import { InlineField, InlineSwitch, VerticalGroup } from '@grafana/ui'; import appEvents from 'app/core/app_events'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import config from 'app/core/config'; import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index d32eb5c181796..017e6adc8a180 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -5,7 +5,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { GrafanaTheme2, TimeRange } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { locationService } from '@grafana/runtime'; +import { config, locationService } from '@grafana/runtime'; import { CustomScrollbar, stylesFactory, Themeable2, withTheme2 } from '@grafana/ui'; import { notifyApp } from 'app/core/actions'; import { Branding } from 'app/core/components/Branding/Branding'; @@ -387,7 +387,8 @@ export class UnthemedDashboardPage extends PureComponent { * Styles */ export const getStyles = stylesFactory((theme: GrafanaTheme2, kioskMode: KioskMode) => { - const contentPadding = kioskMode !== KioskMode.Full ? theme.spacing(0, 2, 2) : theme.spacing(2); + const contentPadding = + kioskMode === KioskMode.Full || config.featureToggles.topnav ? theme.spacing(2) : theme.spacing(0, 2, 2); return { dashboardContainer: css` width: 100%; diff --git a/public/app/features/datasources/DataSourceDashboards.tsx b/public/app/features/datasources/DataSourceDashboards.tsx index 9673716ddc379..9033a94ecc6ce 100644 --- a/public/app/features/datasources/DataSourceDashboards.tsx +++ b/public/app/features/datasources/DataSourceDashboards.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { PluginDashboard, StoreState } from 'app/types'; diff --git a/public/app/features/datasources/DataSourcesListPage.tsx b/public/app/features/datasources/DataSourcesListPage.tsx index f03e7ede1af5a..4535c5b0f769f 100644 --- a/public/app/features/datasources/DataSourcesListPage.tsx +++ b/public/app/features/datasources/DataSourcesListPage.tsx @@ -3,7 +3,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { IconName } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import PageActionBar from 'app/core/components/PageActionBar/PageActionBar'; import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/datasources/NewDataSourcePage.tsx b/public/app/features/datasources/NewDataSourcePage.tsx index b7943e8af90bf..2f226c6978432 100644 --- a/public/app/features/datasources/NewDataSourcePage.tsx +++ b/public/app/features/datasources/NewDataSourcePage.tsx @@ -5,7 +5,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { DataSourcePluginMeta, GrafanaTheme2, NavModel } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { Card, LinkButton, List, PluginSignatureBadge, FilterInput, useStyles2 } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { StoreState } from 'app/types'; import { PluginsErrorsInfo } from '../plugins/components/PluginsErrorsInfo'; diff --git a/public/app/features/datasources/settings/DataSourceSettingsPage.tsx b/public/app/features/datasources/settings/DataSourceSettingsPage.tsx index 68e2a4f2384f1..3630fb0d48fcd 100644 --- a/public/app/features/datasources/settings/DataSourceSettingsPage.tsx +++ b/public/app/features/datasources/settings/DataSourceSettingsPage.tsx @@ -6,7 +6,7 @@ import { selectors } from '@grafana/e2e-selectors'; import { Alert, Button } from '@grafana/ui'; import { cleanUpAction } from 'app/core/actions/cleanUp'; import appEvents from 'app/core/app_events'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/explore/FeatureTogglePage.tsx b/public/app/features/explore/FeatureTogglePage.tsx index 54a00691aaa85..a10df73f18379 100644 --- a/public/app/features/explore/FeatureTogglePage.tsx +++ b/public/app/features/explore/FeatureTogglePage.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; export default function FeatureTogglePage() { const styles = useStyles2( diff --git a/public/app/features/folders/AccessControlFolderPermissions.tsx b/public/app/features/folders/AccessControlFolderPermissions.tsx index 7e5e1b4d3e50c..325b69eb406a7 100644 --- a/public/app/features/folders/AccessControlFolderPermissions.tsx +++ b/public/app/features/folders/AccessControlFolderPermissions.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { Permissions } from 'app/core/components/AccessControl'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/folders/FolderAlerting.tsx b/public/app/features/folders/FolderAlerting.tsx index 939676a751c88..25785b74949bc 100644 --- a/public/app/features/folders/FolderAlerting.tsx +++ b/public/app/features/folders/FolderAlerting.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useAsync } from 'react-use'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/folders/FolderLibraryPanelsPage.tsx b/public/app/features/folders/FolderLibraryPanelsPage.tsx index aa27c268d76ce..a645f34bb5122 100644 --- a/public/app/features/folders/FolderLibraryPanelsPage.tsx +++ b/public/app/features/folders/FolderLibraryPanelsPage.tsx @@ -2,7 +2,8 @@ import React, { useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { useAsync } from 'react-use'; -import Page from '../../core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; + import { GrafanaRouteComponentProps } from '../../core/navigation/types'; import { getNavModel } from '../../core/selectors/navModel'; import { StoreState } from '../../types'; diff --git a/public/app/features/folders/FolderPermissions.tsx b/public/app/features/folders/FolderPermissions.tsx index ed69935fa4fb0..59f9263af8796 100644 --- a/public/app/features/folders/FolderPermissions.tsx +++ b/public/app/features/folders/FolderPermissions.tsx @@ -3,7 +3,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { Tooltip, Icon, Button } from '@grafana/ui'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import AddPermission from 'app/core/components/PermissionList/AddPermission'; import PermissionList from 'app/core/components/PermissionList/PermissionList'; import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo'; diff --git a/public/app/features/folders/FolderSettingsPage.tsx b/public/app/features/folders/FolderSettingsPage.tsx index 16cf9a0392a42..ecb47bb0de206 100644 --- a/public/app/features/folders/FolderSettingsPage.tsx +++ b/public/app/features/folders/FolderSettingsPage.tsx @@ -4,7 +4,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { Button, LegacyForms } from '@grafana/ui'; const { Input } = LegacyForms; import appEvents from 'app/core/app_events'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/folders/components/NewDashboardsFolder.tsx b/public/app/features/folders/components/NewDashboardsFolder.tsx index 72617c8fbfe72..cd387a798179e 100644 --- a/public/app/features/folders/components/NewDashboardsFolder.tsx +++ b/public/app/features/folders/components/NewDashboardsFolder.tsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { Button, Input, Form, Field } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/invites/SignupInvited.tsx b/public/app/features/invites/SignupInvited.tsx index 4d862d6377dd5..d12da280e070c 100644 --- a/public/app/features/invites/SignupInvited.tsx +++ b/public/app/features/invites/SignupInvited.tsx @@ -3,7 +3,7 @@ import { useAsync } from 'react-use'; import { getBackendSrv } from '@grafana/runtime'; import { Button, Field, Form, Input } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getConfig } from 'app/core/config'; import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; diff --git a/public/app/features/library-panels/LibraryPanelsPage.tsx b/public/app/features/library-panels/LibraryPanelsPage.tsx index 09342b0e5cfb1..af435231e7ab2 100644 --- a/public/app/features/library-panels/LibraryPanelsPage.tsx +++ b/public/app/features/library-panels/LibraryPanelsPage.tsx @@ -1,7 +1,8 @@ import React, { FC, useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import Page from '../../core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; + import { GrafanaRouteComponentProps } from '../../core/navigation/types'; import { getNavModel } from '../../core/selectors/navModel'; import { StoreState } from '../../types'; diff --git a/public/app/features/live/pages/CloudAdminPage.tsx b/public/app/features/live/pages/CloudAdminPage.tsx index fe3face9db2cb..449c4c06c3388 100644 --- a/public/app/features/live/pages/CloudAdminPage.tsx +++ b/public/app/features/live/pages/CloudAdminPage.tsx @@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react'; import { GrafanaTheme } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { useStyles } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; import { GrafanaCloudBackend } from './types'; diff --git a/public/app/features/live/pages/FeatureTogglePage.tsx b/public/app/features/live/pages/FeatureTogglePage.tsx index a1d3e635c5ac2..35b19509a05ff 100644 --- a/public/app/features/live/pages/FeatureTogglePage.tsx +++ b/public/app/features/live/pages/FeatureTogglePage.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; export default function FeatureTogglePage() { diff --git a/public/app/features/live/pages/LiveStatusPage.tsx b/public/app/features/live/pages/LiveStatusPage.tsx index 569853591af08..485aacfe8d52b 100644 --- a/public/app/features/live/pages/LiveStatusPage.tsx +++ b/public/app/features/live/pages/LiveStatusPage.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; export default function CloudAdminPage() { diff --git a/public/app/features/live/pages/PipelineAdminPage.tsx b/public/app/features/live/pages/PipelineAdminPage.tsx index 2face908dc6e1..7d33b38b59582 100644 --- a/public/app/features/live/pages/PipelineAdminPage.tsx +++ b/public/app/features/live/pages/PipelineAdminPage.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState, ChangeEvent } from 'react'; import { getBackendSrv } from '@grafana/runtime'; import { Input } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; import { AddNewRule } from './AddNewRule'; diff --git a/public/app/features/manage-dashboards/DashboardImportPage.tsx b/public/app/features/manage-dashboards/DashboardImportPage.tsx index 1085441536a6f..365a7eabd1b95 100644 --- a/public/app/features/manage-dashboards/DashboardImportPage.tsx +++ b/public/app/features/manage-dashboards/DashboardImportPage.tsx @@ -20,7 +20,7 @@ import { withTheme2, } from '@grafana/ui'; import appEvents from 'app/core/app_events'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/manage-dashboards/SnapshotListPage.tsx b/public/app/features/manage-dashboards/SnapshotListPage.tsx index 5aa91777a345c..ae16793ca0f1a 100644 --- a/public/app/features/manage-dashboards/SnapshotListPage.tsx +++ b/public/app/features/manage-dashboards/SnapshotListPage.tsx @@ -2,7 +2,7 @@ import React, { FC } from 'react'; import { MapStateToProps, connect } from 'react-redux'; import { NavModel } from '@grafana/data'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/notifications/NotificationsPage.tsx b/public/app/features/notifications/NotificationsPage.tsx index 04b6b192a2350..22c64301384c3 100644 --- a/public/app/features/notifications/NotificationsPage.tsx +++ b/public/app/features/notifications/NotificationsPage.tsx @@ -1,7 +1,8 @@ import React from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import Page from '../../core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; + import { GrafanaRouteComponentProps } from '../../core/navigation/types'; import { getNavModel } from '../../core/selectors/navModel'; import { StoreState } from '../../types'; diff --git a/public/app/features/org/NewOrgPage.tsx b/public/app/features/org/NewOrgPage.tsx index 34d2619110bd6..6a4fc75a49084 100644 --- a/public/app/features/org/NewOrgPage.tsx +++ b/public/app/features/org/NewOrgPage.tsx @@ -2,7 +2,7 @@ import React, { FC } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { Button, Input, Field, Form } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getConfig } from 'app/core/config'; import { StoreState } from 'app/types'; diff --git a/public/app/features/org/OrgDetailsPage.tsx b/public/app/features/org/OrgDetailsPage.tsx index 5059ad5dd2578..57c21a83a63ed 100644 --- a/public/app/features/org/OrgDetailsPage.tsx +++ b/public/app/features/org/OrgDetailsPage.tsx @@ -3,7 +3,7 @@ import { connect } from 'react-redux'; import { NavModel } from '@grafana/data'; import { VerticalGroup } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import SharedPreferences from 'app/core/components/SharedPreferences/SharedPreferences'; import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/org/SelectOrgPage.tsx b/public/app/features/org/SelectOrgPage.tsx index 273f699cc65a9..2d39f619074a7 100644 --- a/public/app/features/org/SelectOrgPage.tsx +++ b/public/app/features/org/SelectOrgPage.tsx @@ -4,7 +4,7 @@ import { useEffectOnce } from 'react-use'; import { config } from '@grafana/runtime'; import { Button, HorizontalGroup } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { StoreState, UserOrg } from 'app/types'; import { getUserOrganizations, setUserOrganization } from './state/actions'; diff --git a/public/app/features/org/UserInvitePage.tsx b/public/app/features/org/UserInvitePage.tsx index 8afa065a0b7b3..097ead15a32a0 100644 --- a/public/app/features/org/UserInvitePage.tsx +++ b/public/app/features/org/UserInvitePage.tsx @@ -2,7 +2,7 @@ import React, { FC } from 'react'; import { connect } from 'react-redux'; import { NavModel } from '@grafana/data'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types/store'; diff --git a/public/app/features/playlist/PlaylistEditPage.tsx b/public/app/features/playlist/PlaylistEditPage.tsx index c98ba7ee00d3f..24eb413ef12fa 100644 --- a/public/app/features/playlist/PlaylistEditPage.tsx +++ b/public/app/features/playlist/PlaylistEditPage.tsx @@ -4,7 +4,7 @@ import { connect, MapStateToProps } from 'react-redux'; import { NavModel } from '@grafana/data'; import { locationService } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/playlist/PlaylistNewPage.tsx b/public/app/features/playlist/PlaylistNewPage.tsx index c08d288ec998a..e7ef84960b85f 100644 --- a/public/app/features/playlist/PlaylistNewPage.tsx +++ b/public/app/features/playlist/PlaylistNewPage.tsx @@ -4,7 +4,7 @@ import { connect, MapStateToProps } from 'react-redux'; import { NavModel } from '@grafana/data'; import { locationService } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/playlist/PlaylistPage.tsx b/public/app/features/playlist/PlaylistPage.tsx index 62e85085d2f44..e8a997f02320f 100644 --- a/public/app/features/playlist/PlaylistPage.tsx +++ b/public/app/features/playlist/PlaylistPage.tsx @@ -4,7 +4,7 @@ import { useDebounce } from 'react-use'; import { NavModel } from '@grafana/data'; import { ConfirmModal } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import PageActionBar from 'app/core/components/PageActionBar/PageActionBar'; import { getNavModel } from 'app/core/selectors/navModel'; import { contextSrv } from 'app/core/services/context_srv'; diff --git a/public/app/features/plugins/components/AppPluginLoader.tsx b/public/app/features/plugins/components/AppPluginLoader.tsx index fe26327693098..f0300deede4ed 100644 --- a/public/app/features/plugins/components/AppPluginLoader.tsx +++ b/public/app/features/plugins/components/AppPluginLoader.tsx @@ -3,7 +3,7 @@ import { useLocation, useParams } from 'react-router-dom'; import { NavModel } from '@grafana/data'; import { getWarningNav } from 'app/angular/services/nav_model_srv'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import PageLoader from 'app/core/components/PageLoader/PageLoader'; import { useImportAppPlugin } from '../hooks/useImportAppPlugin'; diff --git a/public/app/features/plugins/components/AppRootPage.tsx b/public/app/features/plugins/components/AppRootPage.tsx index c5b7b6c20a1b1..a088cd3fdfd4a 100644 --- a/public/app/features/plugins/components/AppRootPage.tsx +++ b/public/app/features/plugins/components/AppRootPage.tsx @@ -4,7 +4,7 @@ import { createHtmlPortalNode, InPortal, OutPortal, HtmlPortalNode } from 'react import { AppEvents, AppPlugin, AppPluginMeta, KeyValue, NavModel, PluginType } from '@grafana/data'; import { getNotFoundNav, getWarningNav, getExceptionNav } from 'app/angular/services/nav_model_srv'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import PageLoader from 'app/core/components/PageLoader/PageLoader'; import { appEvents } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; diff --git a/public/app/features/profile/ChangePasswordPage.tsx b/public/app/features/profile/ChangePasswordPage.tsx index a5324bc1dbcee..b375c512e9d82 100644 --- a/public/app/features/profile/ChangePasswordPage.tsx +++ b/public/app/features/profile/ChangePasswordPage.tsx @@ -3,7 +3,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { useMount } from 'react-use'; import { NavModel } from '@grafana/data'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/profile/FeatureTogglePage.tsx b/public/app/features/profile/FeatureTogglePage.tsx index 6fd197166ddef..3dd56e287c6af 100644 --- a/public/app/features/profile/FeatureTogglePage.tsx +++ b/public/app/features/profile/FeatureTogglePage.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; export default function FeatureTogglePage() { diff --git a/public/app/features/profile/UserProfileEditPage.tsx b/public/app/features/profile/UserProfileEditPage.tsx index 008893323b08e..446829834ad73 100644 --- a/public/app/features/profile/UserProfileEditPage.tsx +++ b/public/app/features/profile/UserProfileEditPage.tsx @@ -4,7 +4,7 @@ import { useMount } from 'react-use'; import { NavModel } from '@grafana/data'; import { VerticalGroup } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import SharedPreferences from 'app/core/components/SharedPreferences/SharedPreferences'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/sandbox/TestStuffPage.tsx b/public/app/features/sandbox/TestStuffPage.tsx index 7d34b5a9e4e1d..b07b671384259 100644 --- a/public/app/features/sandbox/TestStuffPage.tsx +++ b/public/app/features/sandbox/TestStuffPage.tsx @@ -11,11 +11,11 @@ import { PanelData, } from '@grafana/data'; import { Button, Table } from '@grafana/ui'; +import { Page } from 'app/core/components/Page/Page'; import { config } from 'app/core/config'; import { useAppNotification } from 'app/core/copy/appNotification'; import { QueryGroupOptions } from 'app/types'; -import Page from '../../core/components/Page/Page'; import { PanelRenderer } from '../panel/components/PanelRenderer'; import { QueryGroup } from '../query/components/QueryGroup'; import { PanelQueryRunner } from '../query/state/PanelQueryRunner'; diff --git a/public/app/features/search/components/DashboardListPage.tsx b/public/app/features/search/components/DashboardListPage.tsx index 3ececc199ca14..0bf456dfa96e9 100644 --- a/public/app/features/search/components/DashboardListPage.tsx +++ b/public/app/features/search/components/DashboardListPage.tsx @@ -5,7 +5,7 @@ import { useAsync } from 'react-use'; import { NavModel, locationUtil } from '@grafana/data'; import { config, locationService } from '@grafana/runtime'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { FolderDTO, StoreState } from 'app/types'; diff --git a/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx b/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx index dc6bf19741d96..adaab37e50992 100644 --- a/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx @@ -5,7 +5,7 @@ import { useHistory } from 'react-router-dom'; import { NavModel } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { Form, Button, Input, Field } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker'; import { fetchBuiltinRoles, fetchRoleOptions, updateUserRoles } from 'app/core/components/RolePicker/api'; import { contextSrv } from 'app/core/core'; diff --git a/public/app/features/serviceaccounts/ServiceAccountPage.tsx b/public/app/features/serviceaccounts/ServiceAccountPage.tsx index 82fed275471d7..151174fb63560 100644 --- a/public/app/features/serviceaccounts/ServiceAccountPage.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountPage.tsx @@ -4,7 +4,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { getTimeZone, GrafanaTheme2, NavModel } from '@grafana/data'; import { Button, ConfirmModal, IconButton, useStyles2 } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx b/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx index 6043c9b5e8ec7..78ba47460a56f 100644 --- a/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx @@ -6,7 +6,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { GrafanaTheme2, OrgRole } from '@grafana/data'; import { Alert, ConfirmModal, FilterInput, Icon, LinkButton, RadioButtonGroup, Tooltip, useStyles2 } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import PageLoader from 'app/core/components/PageLoader/PageLoader'; import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; diff --git a/public/app/features/teams/CreateTeam.tsx b/public/app/features/teams/CreateTeam.tsx index 1c35b134e4bd1..395c6a36a6c0b 100644 --- a/public/app/features/teams/CreateTeam.tsx +++ b/public/app/features/teams/CreateTeam.tsx @@ -4,7 +4,7 @@ import { connect } from 'react-redux'; import { NavModel } from '@grafana/data'; import { getBackendSrv, locationService } from '@grafana/runtime'; import { Button, Form, Field, Input, FieldSet } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; diff --git a/public/app/features/teams/TeamList.tsx b/public/app/features/teams/TeamList.tsx index 7f2cda0992b0d..ecaed0f37fb34 100644 --- a/public/app/features/teams/TeamList.tsx +++ b/public/app/features/teams/TeamList.tsx @@ -3,7 +3,7 @@ import React, { PureComponent } from 'react'; import { NavModel } from '@grafana/data'; import { DeleteButton, LinkButton, FilterInput, VerticalGroup, HorizontalGroup, Pagination } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { TeamRolePicker } from 'app/core/components/RolePicker/TeamRolePicker'; import { fetchRoleOptions } from 'app/core/components/RolePicker/api'; import { config } from 'app/core/config'; diff --git a/public/app/features/teams/TeamPages.tsx b/public/app/features/teams/TeamPages.tsx index f72b7f0b53285..505a3a27407c4 100644 --- a/public/app/features/teams/TeamPages.tsx +++ b/public/app/features/teams/TeamPages.tsx @@ -5,7 +5,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { NavModel } from '@grafana/data'; import { featureEnabled } from '@grafana/runtime'; import { Themeable2, withTheme2 } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { UpgradeBox } from 'app/core/components/Upgrade/UpgradeBox'; import config from 'app/core/config'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; diff --git a/public/app/features/users/UsersListPage.tsx b/public/app/features/users/UsersListPage.tsx index 6205a86a7c193..bace46799c83b 100644 --- a/public/app/features/users/UsersListPage.tsx +++ b/public/app/features/users/UsersListPage.tsx @@ -3,7 +3,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { renderMarkdown } from '@grafana/data'; import { HorizontalGroup, Pagination, VerticalGroup } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; +import { Page } from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; import { OrgUser, OrgRole, StoreState } from 'app/types'; From 3a03bbb011f205310417c193f79595fa7b26fd5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 29 Jun 2022 14:26:24 +0200 Subject: [PATCH 02/14] Simplifying PageHeader --- .betterer.results | 8 ++++---- packages/grafana-data/src/types/navModel.ts | 4 ---- public/app/angular/services/nav_model_srv.ts | 1 - public/app/core/components/Page/Page.tsx | 2 +- public/app/core/components/PageHeader/PageHeader.tsx | 10 ++++------ public/app/core/reducers/navModel.ts | 1 - .../features/plugins/components/AppPluginLoader.tsx | 4 ++-- 7 files changed, 11 insertions(+), 19 deletions(-) diff --git a/.betterer.results b/.betterer.results index 95e87d79a52a6..f83d1d2ae52a1 100644 --- a/.betterer.results +++ b/.betterer.results @@ -3111,7 +3111,7 @@ exports[`better eslint`] = { [35, 46, 3, "Unexpected any. Specify a different type.", "193409811"], [37, 26, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/angular/services/nav_model_srv.ts:1949768361": [ + "public/app/angular/services/nav_model_srv.ts:356083867": [ [57, 39, 3, "Unexpected any. Specify a different type.", "193409811"] ], "public/app/angular/services/ng_react.ts:1219930949": [ @@ -3343,9 +3343,9 @@ exports[`better eslint`] = { [39, 32, 10, "Do not use any type assertions.", "883420344"], [39, 39, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/core/components/PageHeader/PageHeader.tsx:952684291": [ + "public/app/core/components/PageHeader/PageHeader.tsx:130343011": [ [65, 22, 22, "Do not use any type assertions.", "4054086100"], - [104, 34, 21, "Do not use any type assertions.", "2401004021"] + [102, 34, 21, "Do not use any type assertions.", "2401004021"] ], "public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx:1614517181": [ [41, 24, 3, "Unexpected any. Specify a different type.", "193409811"], @@ -3555,7 +3555,7 @@ exports[`better eslint`] = { "public/app/core/reducers/appNotification.ts:735507530": [ [77, 35, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/core/reducers/navModel.ts:2486277874": [ + "public/app/core/reducers/navModel.ts:3755863968": [ [7, 20, 41, "Do not use any type assertions.", "680953089"] ], "public/app/core/reducers/processsAclItems.ts:2776156466": [ diff --git a/packages/grafana-data/src/types/navModel.ts b/packages/grafana-data/src/types/navModel.ts index 58f7926152808..453e1a1f57267 100644 --- a/packages/grafana-data/src/types/navModel.ts +++ b/packages/grafana-data/src/types/navModel.ts @@ -56,10 +56,6 @@ export interface NavModel { * This is the current active tab/navigation. */ node: NavModelItem; - /** - * Describes breadcrumbs that are used in places such as data source settings., folder page and plugins page. - */ - breadcrumbs?: NavModelItem[]; } export interface NavModelBreadcrumb { diff --git a/public/app/angular/services/nav_model_srv.ts b/public/app/angular/services/nav_model_srv.ts index 73506625130d6..bf8790e1b3b21 100644 --- a/public/app/angular/services/nav_model_srv.ts +++ b/public/app/angular/services/nav_model_srv.ts @@ -71,7 +71,6 @@ export function getWarningNav(text: string, subTitle?: string): NavModel { icon: 'exclamation-triangle', }; return { - breadcrumbs: [node], node: node, main: node, }; diff --git a/public/app/core/components/Page/Page.tsx b/public/app/core/components/Page/Page.tsx index 121b9ba1548c5..4f8252bf4bc37 100644 --- a/public/app/core/components/Page/Page.tsx +++ b/public/app/core/components/Page/Page.tsx @@ -39,7 +39,7 @@ export const Page: PageType = ({ navModel, children, className, ...otherProps })
    - {navModel && } + {navModel && } {children}
    diff --git a/public/app/core/components/PageHeader/PageHeader.tsx b/public/app/core/components/PageHeader/PageHeader.tsx index 116ff8186dde6..86a67427029f1 100644 --- a/public/app/core/components/PageHeader/PageHeader.tsx +++ b/public/app/core/components/PageHeader/PageHeader.tsx @@ -1,14 +1,14 @@ import { css } from '@emotion/css'; import React, { FC } from 'react'; -import { NavModel, NavModelItem, NavModelBreadcrumb, GrafanaTheme2 } from '@grafana/data'; +import { NavModelItem, NavModelBreadcrumb, GrafanaTheme2 } from '@grafana/data'; import { Tab, TabsBar, Icon, IconName, useStyles2 } from '@grafana/ui'; import { PanelHeaderMenuItem } from 'app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem'; import { ProBadge } from '../Upgrade/ProBadge'; export interface Props { - model: NavModel; + model: NavModelItem; } const SelectNav = ({ children, customCss }: { children: NavModelItem[]; customCss: string }) => { @@ -82,14 +82,12 @@ export const PageHeader: FC = ({ model }) => { return null; } - const main = model.main; - const children = main.children; return (
    - {renderHeaderTitle(main)} - {children && children.length && {children}} + {renderHeaderTitle(model)} + {model.children && model.children.length > 0 && {model.children}}
    diff --git a/public/app/core/reducers/navModel.ts b/public/app/core/reducers/navModel.ts index bdb256bfe1a9f..6be4673248da5 100644 --- a/public/app/core/reducers/navModel.ts +++ b/public/app/core/reducers/navModel.ts @@ -32,7 +32,6 @@ function buildWarningNav(text: string, subTitle?: string): NavModel { icon: 'exclamation-triangle', }; return { - breadcrumbs: [node], node: node, main: node, }; diff --git a/public/app/features/plugins/components/AppPluginLoader.tsx b/public/app/features/plugins/components/AppPluginLoader.tsx index fe26327693098..15450c3473621 100644 --- a/public/app/features/plugins/components/AppPluginLoader.tsx +++ b/public/app/features/plugins/components/AppPluginLoader.tsx @@ -23,13 +23,13 @@ export const AppPluginLoader = ({ id, basePath }: AppPluginLoaderProps) => { const { pathname } = useLocation(); if (error) { - return ; + return ; } return ( <> {loading && } - {nav && } + {nav && } {!loading && plugin && plugin.root && ( Date: Wed, 29 Jun 2022 18:33:57 +0200 Subject: [PATCH 03/14] Progress on a new model that can more easily support new and old page layouts --- .betterer.results | 62 +++++++++---------- public/app/angular/angular_wrappers.ts | 2 +- public/app/core/components/Page/Page.tsx | 36 ++++++----- .../app/core/components/Page/usePageTitle.ts | 20 ++++++ .../components/PageHeader/PageHeader.test.tsx | 6 +- .../core/components/PageHeader/PageHeader.tsx | 6 +- .../core/components/PageLayouts/NewPage.tsx | 61 +++--------------- .../components/PageLayouts/PageHeader.tsx | 43 +++++++++++++ .../core/components/PageLayouts/PageTabs.tsx | 43 +++++++++++++ .../plugins/components/AppPluginLoader.tsx | 4 +- .../ServiceAccountCreatePage.test.tsx | 4 +- .../ServiceAccountCreatePage.tsx | 18 ++---- .../ServiceAccountPage.test.tsx | 8 --- .../serviceaccounts/ServiceAccountPage.tsx | 8 +-- .../ServiceAccountsListPage.test.tsx | 8 --- .../ServiceAccountsListPage.tsx | 5 +- public/app/features/teams/CreateTeam.test.tsx | 9 +-- public/app/features/teams/CreateTeam.tsx | 22 +------ public/app/features/teams/TeamList.test.tsx | 9 --- public/app/features/teams/TeamList.tsx | 8 +-- public/app/features/teams/TeamPages.test.tsx | 4 +- public/app/features/teams/TeamPages.tsx | 20 +++--- public/app/features/teams/TeamPermissions.tsx | 2 +- .../app/features/users/UsersListPage.test.tsx | 9 --- public/app/features/users/UsersListPage.tsx | 6 +- 25 files changed, 202 insertions(+), 221 deletions(-) create mode 100644 public/app/core/components/Page/usePageTitle.ts create mode 100644 public/app/core/components/PageLayouts/PageHeader.tsx create mode 100644 public/app/core/components/PageLayouts/PageTabs.tsx diff --git a/.betterer.results b/.betterer.results index 6861d03135117..bb3631d47754c 100644 --- a/.betterer.results +++ b/.betterer.results @@ -3337,18 +3337,18 @@ exports[`better eslint`] = { "public/app/core/components/OptionsUI/strings.tsx:1826340875": [ [24, 16, 42, "Do not use any type assertions.", "3301854123"] ], - "public/app/core/components/PageHeader/PageHeader.test.tsx:3755271251": [ - [19, 32, 10, "Do not use any type assertions.", "883420344"], - [19, 39, 3, "Unexpected any. Specify a different type.", "193409811"], - [39, 32, 10, "Do not use any type assertions.", "883420344"], - [39, 39, 3, "Unexpected any. Specify a different type.", "193409811"] + "public/app/core/components/PageHeader/PageHeader.test.tsx:1328635381": [ + [19, 34, 10, "Do not use any type assertions.", "883420344"], + [19, 41, 3, "Unexpected any. Specify a different type.", "193409811"], + [39, 34, 10, "Do not use any type assertions.", "883420344"], + [39, 41, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/core/components/PageHeader/PageHeader.tsx:130343011": [ + "public/app/core/components/PageHeader/PageHeader.tsx:3742780580": [ [65, 22, 22, "Do not use any type assertions.", "4054086100"], [102, 34, 21, "Do not use any type assertions.", "2401004021"] ], - "public/app/core/components/PageLayouts/NewPage.tsx:4153212563": [ - [66, 34, 22, "Do not use any type assertions.", "4054086100"] + "public/app/core/components/PageLayouts/PageTabs.tsx:3543915334": [ + [24, 22, 22, "Do not use any type assertions.", "4054086100"] ], "public/app/core/components/PageLayouts/SectionNav.tsx:1750474659": [ [20, 34, 21, "Do not use any type assertions.", "2401004021"] @@ -5028,7 +5028,7 @@ exports[`better eslint`] = { [264, 15, 56, "Do not use any type assertions.", "2674630592"], [266, 13, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/dashboard/containers/DashboardPage.tsx:3380941351": [ + "public/app/features/dashboard/containers/DashboardPage.tsx:3836168909": [ [108, 36, 40, "Do not use any type assertions.", "2547843745"], [108, 73, 3, "Unexpected any. Specify a different type.", "193409811"], [144, 32, 40, "Do not use any type assertions.", "2547843745"], @@ -6777,7 +6777,7 @@ exports[`better eslint`] = { [12, 13, 3, "Unexpected any. Specify a different type.", "193409811"], [41, 9, 43, "Do not use any type assertions.", "4109129169"] ], - "public/app/features/sandbox/TestStuffPage.tsx:1930871651": [ + "public/app/features/sandbox/TestStuffPage.tsx:1454935587": [ [134, 30, 29, "Do not use any type assertions.", "3195381622"] ], "public/app/features/search/components/DashboardSearch.test.tsx:3245889886": [ @@ -6935,23 +6935,20 @@ exports[`better eslint`] = { [246, 28, 17, "Do not use any type assertions.", "1811834489"], [251, 5, 29, "Do not use any type assertions.", "4135357902"] ], - "public/app/features/serviceaccounts/ServiceAccountPage.test.tsx:3979425477": [ - [33, 20, 23, "Do not use any type assertions.", "499357842"], - [44, 13, 9, "Do not use any type assertions.", "3692209159"], - [44, 19, 3, "Unexpected any. Specify a different type.", "193409811"], - [45, 14, 9, "Do not use any type assertions.", "3692209159"], - [45, 20, 3, "Unexpected any. Specify a different type.", "193409811"], - [47, 11, 9, "Do not use any type assertions.", "3692209159"], - [47, 17, 3, "Unexpected any. Specify a different type.", "193409811"] + "public/app/features/serviceaccounts/ServiceAccountPage.test.tsx:3401231959": [ + [25, 20, 23, "Do not use any type assertions.", "499357842"], + [36, 13, 9, "Do not use any type assertions.", "3692209159"], + [36, 19, 3, "Unexpected any. Specify a different type.", "193409811"], + [37, 14, 9, "Do not use any type assertions.", "3692209159"], + [37, 20, 3, "Unexpected any. Specify a different type.", "193409811"], + [39, 11, 9, "Do not use any type assertions.", "3692209159"], + [39, 17, 3, "Unexpected any. Specify a different type.", "193409811"] ], "public/app/features/serviceaccounts/state/reducers.ts:816482675": [ [13, 18, 23, "Do not use any type assertions.", "499357842"], [15, 10, 14, "Do not use any type assertions.", "2767045528"], [43, 19, 25, "Do not use any type assertions.", "1122467828"] ], - "public/app/features/teams/CreateTeam.test.tsx:136903941": [ - [30, 14, 34, "Do not use any type assertions.", "463003776"] - ], "public/app/features/teams/TeamGroupSync.test.tsx:2647720693": [ [12, 12, 17, "Do not use any type assertions.", "2242876437"] ], @@ -6959,12 +6956,11 @@ exports[`better eslint`] = { [59, 32, 3, "Unexpected any. Specify a different type.", "193409811"], [63, 23, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/teams/TeamList.test.tsx:2054736348": [ - [22, 14, 123, "Do not use any type assertions.", "695951401"], - [30, 11, 12, "Do not use any type assertions.", "1079483306"], - [40, 18, 59, "Do not use any type assertions.", "25768610"], - [67, 24, 77, "Do not use any type assertions.", "361803129"], - [84, 24, 77, "Do not use any type assertions.", "1295202722"] + "public/app/features/teams/TeamList.test.tsx:3686781523": [ + [21, 11, 12, "Do not use any type assertions.", "1079483306"], + [31, 18, 59, "Do not use any type assertions.", "25768610"], + [58, 24, 77, "Do not use any type assertions.", "361803129"], + [75, 24, 77, "Do not use any type assertions.", "1295202722"] ], "public/app/features/teams/TeamMemberRow.tsx:607934811": [ [41, 18, 20, "Do not use any type assertions.", "3089389535"] @@ -6976,16 +6972,15 @@ exports[`better eslint`] = { "public/app/features/teams/TeamMembers.tsx:4139991775": [ [19, 32, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/teams/TeamPages.test.tsx:1955453068": [ + "public/app/features/teams/TeamPages.test.tsx:648699836": [ [63, 13, 86, "Do not use any type assertions.", "2945747797"], [68, 11, 3, "Unexpected any. Specify a different type.", "193409811"], - [70, 14, 34, "Do not use any type assertions.", "463003776"], [75, 10, 10, "Do not use any type assertions.", "1584692172"], [76, 13, 18, "Do not use any type assertions.", "2776323642"], [79, 18, 88, "Do not use any type assertions.", "2247670218"], [138, 20, 95, "Do not use any type assertions.", "4068964415"] ], - "public/app/features/teams/TeamPages.tsx:2748675066": [ + "public/app/features/teams/TeamPages.tsx:4058522017": [ [52, 43, 18, "Do not use any type assertions.", "373851894"] ], "public/app/features/teams/state/reducers.ts:1856799550": [ @@ -7191,10 +7186,9 @@ exports[`better eslint`] = { "public/app/features/users/UsersActionBar.tsx:1795710611": [ [66, 32, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/features/users/UsersListPage.test.tsx:4284943401": [ - [27, 14, 119, "Do not use any type assertions.", "1781051572"], - [35, 11, 15, "Do not use any type assertions.", "2789568508"], - [36, 14, 15, "Do not use any type assertions.", "3505843099"] + "public/app/features/users/UsersListPage.test.tsx:2080788337": [ + [25, 11, 15, "Do not use any type assertions.", "2789568508"], + [26, 14, 15, "Do not use any type assertions.", "3505843099"] ], "public/app/features/users/UsersTable.test.tsx:2179189208": [ [19, 11, 15, "Do not use any type assertions.", "2789568508"] diff --git a/public/app/angular/angular_wrappers.ts b/public/app/angular/angular_wrappers.ts index 15159553cd740..30a63a5af02a6 100644 --- a/public/app/angular/angular_wrappers.ts +++ b/public/app/angular/angular_wrappers.ts @@ -17,7 +17,7 @@ import { QueryEditor as CloudMonitoringQueryEditor } from 'app/plugins/datasourc import EmptyListCTA from '../core/components/EmptyListCTA/EmptyListCTA'; import { Footer } from '../core/components/Footer/Footer'; -import PageHeader from '../core/components/PageHeader/PageHeader'; +import { PageHeader } from '../core/components/PageHeader/PageHeader'; import { MetricSelect } from '../core/components/Select/MetricSelect'; import { TagFilter } from '../core/components/TagFilter/TagFilter'; import { HelpModal } from '../core/components/help/HelpModal'; diff --git a/public/app/core/components/Page/Page.tsx b/public/app/core/components/Page/Page.tsx index 03704f1a65f62..2ebfc97782243 100644 --- a/public/app/core/components/Page/Page.tsx +++ b/public/app/core/components/Page/Page.tsx @@ -1,23 +1,27 @@ // Libraries import { css, cx } from '@emotion/css'; -import React, { FC, HTMLAttributes, useEffect } from 'react'; +import React, { FC, HTMLAttributes } from 'react'; +import { useSelector } from 'react-redux'; +import { createSelector } from 'reselect'; -import { GrafanaTheme2, NavModel } from '@grafana/data'; +import { GrafanaTheme2, NavModel, NavModelItem } from '@grafana/data'; import { config } from '@grafana/runtime'; import { CustomScrollbar, useStyles2 } from '@grafana/ui'; -import { getTitleFromNavModel } from 'app/core/selectors/navModel'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types'; -// Components -import { Branding } from '../Branding/Branding'; import { Footer } from '../Footer/Footer'; -import PageHeader from '../PageHeader/PageHeader'; +import { PageHeader } from '../PageHeader/PageHeader'; import { NewPage } from '../PageLayouts/NewPage'; import { PageContents } from './PageContents'; +import { usePageTitle } from './usePageTitle'; interface Props extends HTMLAttributes { children: React.ReactNode; + navId?: string; navModel?: NavModel; + pageNav?: NavModelItem; } export interface PageType extends FC { @@ -25,23 +29,19 @@ export interface PageType extends FC { Contents: typeof PageContents; } -export const OldPage: PageType = ({ navModel, children, className, ...otherProps }) => { +export const OldPage: PageType = ({ navId, navModel: oldNavProp, pageNav, children, className, ...otherProps }) => { const styles = useStyles2(getStyles); + const navModel = useSelector( + createSelector(getNavIndex, (navIndex) => oldNavProp ?? getNavModel(navIndex, navId ?? 'home')) + ); - useEffect(() => { - if (navModel) { - const title = getTitleFromNavModel(navModel); - document.title = title ? `${title} - ${Branding.AppTitle}` : Branding.AppTitle; - } else { - document.title = Branding.AppTitle; - } - }, [navModel]); + usePageTitle(navModel, pageNav); return (
    - {navModel && } + {children}
    @@ -62,3 +62,7 @@ const getStyles = (_: GrafanaTheme2) => ({ min-height: 0; `, }); + +function getNavIndex(store: StoreState) { + return store.navIndex; +} diff --git a/public/app/core/components/Page/usePageTitle.ts b/public/app/core/components/Page/usePageTitle.ts new file mode 100644 index 0000000000000..bd96cef3c5331 --- /dev/null +++ b/public/app/core/components/Page/usePageTitle.ts @@ -0,0 +1,20 @@ +import { useEffect } from 'react'; + +import { NavModel, NavModelItem } from '@grafana/data'; + +import { Branding } from '../Branding/Branding'; + +export function usePageTitle(navModel?: NavModel, pageNav?: NavModelItem) { + useEffect(() => { + if (navModel) { + const title = getTitleFromNavModel(navModel); + document.title = title ? `${title} - ${Branding.AppTitle}` : Branding.AppTitle; + } else { + document.title = Branding.AppTitle; + } + }, [navModel, pageNav]); +} + +export const getTitleFromNavModel = (navModel: NavModel) => { + return `${navModel.main.text}${navModel.node.text ? ': ' + navModel.node.text : ''}`; +}; diff --git a/public/app/core/components/PageHeader/PageHeader.test.tsx b/public/app/core/components/PageHeader/PageHeader.test.tsx index 2965d00714260..2f7673330c1c7 100644 --- a/public/app/core/components/PageHeader/PageHeader.test.tsx +++ b/public/app/core/components/PageHeader/PageHeader.test.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import PageHeader from './PageHeader'; +import { PageHeader } from './PageHeader'; describe('PageHeader', () => { describe('when the nav tree has a node with a title', () => { @@ -17,7 +17,7 @@ describe('PageHeader', () => { node: {}, }; - render(); + render(); expect(screen.getByRole('heading', { name: 'node' })).toBeInTheDocument(); }); @@ -37,7 +37,7 @@ describe('PageHeader', () => { node: {}, }; - render(); + render(); expect(screen.getByRole('heading', { name: 'Parent / child' })).toBeInTheDocument(); expect(screen.getByRole('link', { name: 'Parent' })).toBeInTheDocument(); diff --git a/public/app/core/components/PageHeader/PageHeader.tsx b/public/app/core/components/PageHeader/PageHeader.tsx index 86a67427029f1..45fe58f14743a 100644 --- a/public/app/core/components/PageHeader/PageHeader.tsx +++ b/public/app/core/components/PageHeader/PageHeader.tsx @@ -8,7 +8,7 @@ import { PanelHeaderMenuItem } from 'app/features/dashboard/dashgrid/PanelHeader import { ProBadge } from '../Upgrade/ProBadge'; export interface Props { - model: NavModelItem; + navItem: NavModelItem; } const SelectNav = ({ children, customCss }: { children: NavModelItem[]; customCss: string }) => { @@ -75,7 +75,7 @@ const Navigation = ({ children }: { children: NavModelItem[] }) => { ); }; -export const PageHeader: FC = ({ model }) => { +export const PageHeader: FC = ({ navItem: model }) => { const styles = useStyles2(getStyles); if (!model) { @@ -155,5 +155,3 @@ const getStyles = (theme: GrafanaTheme2) => ({ background: ${theme.colors.background.canvas}; `, }); - -export default PageHeader; diff --git a/public/app/core/components/PageLayouts/NewPage.tsx b/public/app/core/components/PageLayouts/NewPage.tsx index 624af2eceddab..e46c0af9e229b 100644 --- a/public/app/core/components/PageLayouts/NewPage.tsx +++ b/public/app/core/components/PageLayouts/NewPage.tsx @@ -2,21 +2,23 @@ import { css, cx } from '@emotion/css'; import React, { HTMLAttributes, useEffect, FC } from 'react'; -import { GrafanaTheme2, NavModel } from '@grafana/data'; -import { CustomScrollbar, IconName, Tab, TabsBar, useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2, NavModel, NavModelItem } from '@grafana/data'; +import { CustomScrollbar, useStyles2 } from '@grafana/ui'; import { getTitleFromNavModel } from 'app/core/selectors/navModel'; // Components import { Branding } from '../Branding/Branding'; import { Footer } from '../Footer/Footer'; -import PageHeader from '../PageHeader/PageHeader'; import { PageContents } from './PageContents'; +import { PageHeader } from './PageHeader'; +import { PageTabs } from './PageTabs'; import { SectionNav } from './SectionNav'; interface Props extends HTMLAttributes { children: React.ReactNode; navModel?: NavModel; + pageNav?: NavModelItem; } export interface PageType extends FC { @@ -24,7 +26,7 @@ export interface PageType extends FC { Contents: typeof PageContents; } -export const NewPage: PageType = ({ navModel, children, className, ...otherProps }: Props) => { +export const NewPage: PageType = ({ navModel, pageNav, children, className, ...otherProps }: Props) => { const styles = useStyles2(getStyles); useEffect(() => { @@ -47,35 +49,9 @@ export const NewPage: PageType = ({ navModel, children, className, ...otherProps
    -

    - {navModel.node.img && ( - {`logo - )} - {navModel.node.text} -

    - {navModel.node.subTitle &&
    {navModel.node.subTitle}
    } - {navModel.node.children && ( - <> - - {navModel.node.children.map((child, index) => { - return ( - !child.hideFromTabs && ( - - ) - ); - })} - -
    {children}
    - - )} - {!navModel.node.children && children} + + {pageNav && pageNav.children && } + {children}