Skip to content

Commit

Permalink
Rares/grafana9.3 navbar latest (#758)
Browse files Browse the repository at this point in the history
* new nav changes in progress

* navbar changes

* navbar

* working navbar

* got rid of deprecated usages from @grafana/*

* removed duplicated headers

* navbar changes

* path fix for links

* old navbar support through navbarRootFallback

* alignment

* minor changes

* breadcrumb fix

* header

* tabs and header for legacy navigation

* nav fix

* more fixes :)

* refactored sass rule

* docker file

* docker source image

* eslint added ^plugin to settings

* docker host

* fix

* test fix

* bring back team selector

* cleanup

* linter fix

* navbar chatops changes

* navbar

* added component to display header in legacy navbar

* fixed headings

* linter changes

* default route

* navbar class fallback

* permission checks for viewing cloud/live settings

* fixed styling for legacy

* linter + docker

* legacy handling of hideFromTabs

* init tabs logic

* renamed to isTopNavbar

* refactor

* some refactoring

* fix deprecated query usage

* temporarily disable test for webhooks

* reverted docker file to original content
  • Loading branch information
teodosii authored Nov 16, 2022
1 parent f9a9c1d commit 83f281c
Show file tree
Hide file tree
Showing 77 changed files with 2,037 additions and 2,222 deletions.
2 changes: 1 addition & 1 deletion grafana-plugin/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
plugins: ['rulesdir', 'import'],
settings: {
'import/internal-regex':
'^assets|^components|^containers|^declare|^icons|^img|^interceptors|^models|^network|^pages|^services|^state|^utils',
'^assets|^components|^containers|^declare|^icons|^img|^interceptors|^models|^network|^pages|^services|^state|^utils|^plugin',
},
rules: {
eqeqeq: 'warn',
Expand Down
1 change: 1 addition & 0 deletions grafana-plugin/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ module.exports = {
'^jest$': '<rootDir>/src/jest',
'^.+\\.(css|scss)$': '<rootDir>/src/jest/styleMock.ts',
'^lodash-es$': 'lodash',
"^.+\\.svg$": "<rootDir>/src/jest/svgTransform.ts"
},
};
10 changes: 5 additions & 5 deletions grafana-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@
"@babel/preset-env": "^7.18.10",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@grafana/data": "9.1.1",
"@grafana/data": "^9.2.4",
"@grafana/eslint-config": "^5.0.0",
"@grafana/runtime": "9.1.1",
"@grafana/toolkit": "9.1.1",
"@grafana/ui": "9.1.1",
"@jest/globals": "27.5.1",
"@grafana/runtime": "^9.2.4",
"@grafana/toolkit": "^9.2.4",
"@grafana/ui": "^9.2.4",
"@jest/globals": "^27.5.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "12",
"@types/dompurify": "^2.3.4",
Expand Down
28 changes: 28 additions & 0 deletions grafana-plugin/src/PluginPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';

import { PluginPageProps, PluginPage as RealPluginPage } from '@grafana/runtime';
import Header from 'navbar/Header/Header';

import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
import { useStore } from 'state/useStore';
import { useQueryParams } from 'utils/hooks';

export const PluginPage = (isTopNavbar() ? RealPlugin : PluginPageFallback) as React.ComponentType<PluginPageProps>;

function RealPlugin(props: PluginPageProps): React.ReactNode {
const store = useStore();

const queryParams = useQueryParams();
const page = queryParams.get('page');

return (
<RealPluginPage {...props}>
<Header page={page} backendLicense={store.backendLicense} />
{props.children}
</RealPluginPage>
);
}

function PluginPageFallback(props: PluginPageProps): React.ReactNode {
return props.children;
}
30 changes: 0 additions & 30 deletions grafana-plugin/src/components/NavBar/NavBarSubtitle.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,26 @@ export default function PageErrorHandlingWrapper({
itemNotFoundMessage,
children,
}: {
errorData: PageErrorData;
objectName: string;
errorData?: PageErrorData;
objectName?: string;
pageName: string;
itemNotFoundMessage?: string;
children: () => JSX.Element;
}) {
children: React.ReactNode;
}): JSX.Element {
useEffect(() => {
if (!errorData) {
return;
}
const { isWrongTeamError, isNotFoundError } = errorData;
if (!isWrongTeamError && isNotFoundError && itemNotFoundMessage) {
openWarningNotification(itemNotFoundMessage);
}
}, [errorData.isNotFoundError]);
}, [errorData?.isNotFoundError]);

const store = useStore();

if (!errorData.isWrongTeamError) {
return children();
if (!errorData || !errorData.isWrongTeamError) {
return <>{children}</>;
}

const currentTeamId = store.userStore.currentUser?.current_team;
Expand Down
24 changes: 18 additions & 6 deletions grafana-plugin/src/components/PluginLink/PluginLink.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import React, { useCallback, FC } from 'react';

import { getLocationSrv } from '@grafana/runtime';
import { LocationUpdate } from '@grafana/runtime/services/LocationSrv';
import { locationService } from '@grafana/runtime';
import cn from 'classnames/bind';
import qs from 'query-string';

import { PLUGIN_URL_PATH } from 'pages';

import styles from './PluginLink.module.css';

interface PluginLinkProps extends LocationUpdate {
interface PluginLinkProps {
disabled?: boolean;
className?: string;
wrap?: boolean;
children: any;
partial?: boolean;
path?: string;
query?: Record<string, any>;
}

const cx = cn.bind(styles);

const PluginLink: FC<PluginLinkProps> = (props) => {
const { children, partial = false, path = '/a/grafana-oncall-app/', query, disabled, className, wrap = true } = props;
const { children, partial = false, path = PLUGIN_URL_PATH, query, disabled, className, wrap = true } = props;

const href = `${path}?${qs.stringify(query)}`;
const href = `${path}/?${qs.stringify(query)}`;

const onClickCallback = useCallback(
(event) => {
Expand All @@ -30,7 +34,15 @@ const PluginLink: FC<PluginLinkProps> = (props) => {
return;
}

!disabled && getLocationSrv().update({ partial, path, query });
if (disabled) {
return;
}

if (partial) {
locationService.partial(query);
} else {
locationService.push(href);
}
},
[children]
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
.root {
margin-top: -24px;
}

.root .alerts_horizontal {
height: 100%;
display: flex;
gap: 10px;
}
flex-direction: column;

.alerts_horizontal {
display: flex;
gap: 10px;
}

.root .alert {
margin: 24px 0;
.alert {
margin: 24px 0;
}
}

/* --- GRAFANA UI TUNINGS --- */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ import { getItem, setItem } from 'utils/localStorage';
import sanitize from 'utils/sanitize';

import { getSlackMessage } from './DefaultPageLayout.helpers';
import styles from './DefaultPageLayout.module.scss';
import { SlackError } from './DefaultPageLayout.types';

import styles from './DefaultPageLayout.module.css';

const cx = cn.bind(styles);

interface DefaultPageLayoutProps extends AppRootProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@
position: absolute;
padding: 16px 0;
margin-right: 24px;

&--topRight {
right: 14px;
top: 12px;
}
&--topRightIncident {
right: 32px;
top: 36px;
}
}

.teamSelectLabel {
display: flex;
}

.teamSelectLink {
position: absolute;
right: 0;
margin-left: auto;
}

.teamSelectInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import PluginLink from 'components/PluginLink/PluginLink';
import GSelect from 'containers/GSelect/GSelect';
import { WithPermissionControl } from 'containers/WithPermissionControl/WithPermissionControl';
import { GrafanaTeam } from 'models/grafana_team/grafana_team.types';
import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers';
import { useStore } from 'state/useStore';
import { UserAction } from 'state/userAction';

import styles from './GrafanaTeamSelect.module.css';
import styles from './GrafanaTeamSelect.module.scss';

const cx = cn.bind(styles);

Expand Down Expand Up @@ -47,34 +48,37 @@ const GrafanaTeamSelect = observer((props: GrafanaTeamSelectProps) => {
}
};

const content = (
<div className={cx('teamSelect', { 'teamSelect--topRight': isTopNavbar() })}>
<div className={cx('teamSelectLabel')}>
<Label>
Select Team{' '}
<Tooltip content="The objects on this page are filtered by team and you can only view the objects that belong to your team. Note that filtering within Grafana OnCall is meant for usability, not access management.">
<Icon name="info-circle" size="md" className={cx('teamSelectInfo')}></Icon>
</Tooltip>
</Label>
<WithPermissionControl userAction={UserAction.UpdateTeams}>
<PluginLink path="/org/teams" className={cx('teamSelectLink')}>
Edit teams
</PluginLink>
</WithPermissionControl>
</div>
<GSelect
modelName="grafanaTeamStore"
displayField="name"
valueField="id"
placeholder="Select Team"
className={cx('select', 'control')}
value={user.current_team}
onChange={onTeamChange}
/>
</div>
);

return document.getElementsByClassName('page-header__inner')[0]
? ReactDOM.createPortal(
<div className={cx('teamSelect')}>
<div className={cx('teamSelectLabel')}>
<Label>
Select Team{' '}
<Tooltip content="The objects on this page are filtered by team and you can only view the objects that belong to your team. Note that filtering within Grafana OnCall is meant for usability, not access management.">
<Icon name="info-circle" size="md" className={cx('teamSelectInfo')}></Icon>
</Tooltip>
</Label>
<WithPermissionControl userAction={UserAction.UpdateTeams}>
<PluginLink path="/org/teams" className={cx('teamSelectLink')}>
Edit teams
</PluginLink>
</WithPermissionControl>
</div>
<GSelect
modelName="grafanaTeamStore"
displayField="name"
valueField="id"
placeholder="Select Team"
className={cx('select', 'control')}
value={user.current_team}
onChange={onTeamChange}
/>
</div>,
document.getElementsByClassName('page-header__inner')[0]
)
? ReactDOM.createPortal(content, document.getElementsByClassName('page-header__inner')[0])
: isTopNavbar()
? content
: null;
});

Expand Down
26 changes: 26 additions & 0 deletions grafana-plugin/src/img/grafanaGlobalStyles.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
/* Navigation/Layout */

.page-body {
max-width: unset !important;
}

.oncall-header {
padding-top: 0;
padding-bottom: 36px;
}

.scrollbar-view [class*='-page-header'] {
margin-bottom: 0 !important;
}

.page-container.page-body {
flex-grow: 1 !important;
}

.page-container {
max-width: unset !important;
flex-grow: unset !important;
flex-basis: unset !important;
}

.page-scrollbar-content > div:first-child {
flex-grow: 1;
}

.page-header__title {
padding-top: 0 !important;
margin-right: 8px;
}

/* This is for Grafana 8, remove later */
Expand Down
8 changes: 8 additions & 0 deletions grafana-plugin/src/jest/svgTransform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
process() {
return { code: 'module.exports = {};' };
},
getCacheKey() {
return 'svgTransform';
},
};
2 changes: 1 addition & 1 deletion grafana-plugin/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ComponentClass } from 'react';

import { AppPlugin, AppPluginMeta, AppRootProps, PluginConfigPageProps } from '@grafana/data';
import { GrafanaPluginRootPage } from 'GrafanaPluginRootPage';

import { PluginConfigPage } from 'containers/PluginConfigPage/PluginConfigPage';
import { GrafanaPluginRootPage } from 'plugin/GrafanaPluginRootPage';

import { OnCallAppSettings } from './types';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
.root {
display: flex;
align-items: center;
}

.navbar-star-icon {
margin-right: 4px;
}
Expand All @@ -13,9 +8,11 @@
border: 1px solid var(--gray-9);
width: initial;
font-size: 12px;
padding-top: 0;
}

.navbar-link {
display: flex;
align-items: center;
padding-top: 6px;
}
Loading

0 comments on commit 83f281c

Please sign in to comment.