[OBS] Editing navigation docs adding badge information (#108530)
* Adding badge description * apm-new-badge_docs * adding warning * addressing PR comments * changing i18n * adjusting docs * addressing PR comments Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
7b03175395
commit
512ab2d82f
|
@ -95,10 +95,6 @@ const backendsTitle = i18n.translate('xpack.apm.navigation.backendsTitle', {
|
|||
defaultMessage: 'Backends',
|
||||
});
|
||||
|
||||
const newBadgeLabel = i18n.translate('xpack.apm.navigation.newBadge', {
|
||||
defaultMessage: 'NEW',
|
||||
});
|
||||
|
||||
export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
|
||||
constructor(
|
||||
private readonly initializerContext: PluginInitializerContext<ConfigSchema>
|
||||
|
@ -131,7 +127,7 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
|
|||
label: backendsTitle,
|
||||
app: 'apm',
|
||||
path: '/backends',
|
||||
sideBadgeLabel: newBadgeLabel,
|
||||
isNewFeature: true,
|
||||
onClick: () => {
|
||||
const { usageCollection } = pluginsStart as {
|
||||
usageCollection?: UsageCollectionStart;
|
||||
|
|
|
@ -44,6 +44,8 @@ export interface NavigationEntry {
|
|||
matchFullPath?: boolean;
|
||||
// whether to ignore trailing slashes, defaults to `true`
|
||||
ignoreTrailingSlash?: boolean;
|
||||
// shows NEW badge besides the navigation label, which will automatically disappear when menu item is clicked.
|
||||
isNewFeature?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -140,3 +142,33 @@ The `<ObservabilityPageTemplate />` component is a wrapper around the `<KibanaPa
|
|||
After these two steps we should see something like the following (note the navigation on the left):
|
||||
|
||||
![Page template rendered example](./page_template.png)
|
||||
|
||||
## Adding NEW badge
|
||||
|
||||
You can add a NEW badge beside the label by using the property `isNewFeature?: boolean;`.
|
||||
|
||||
```js
|
||||
setup(core: CoreSetup, plugins: PluginsSetup) {
|
||||
plugins.observability.navigation.registerSections(
|
||||
of([
|
||||
{
|
||||
label: 'A solution section',
|
||||
sortKey: 200,
|
||||
entries: [
|
||||
{ label: 'Backends', app: 'exampleA', path: '/example', isNewFeature: true },
|
||||
],
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
![NEW Badge example](./badge.png)
|
||||
|
||||
The badge is going to be shown until user clicks on the menu item for the first time. Then we'll save an information at local storage, following this pattern `observability.nav_item_badge_visible_${app}${path}`, the above example would save `observability.nav_item_badge_visible_exampleA/example`. And the badge is removed. It'll only show again if the item saved at local storage is removed or set to `false`.
|
||||
|
||||
It's recommended to remove the badge (e.g. a new feature promotion) in the subsequent release.
|
||||
|
||||
To avoid the navigation flooding with badges, we also want to propose keeping it to maximum 2 active badges for every iteration
|
||||
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
|
@ -5,13 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import { EuiBadge } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
badgeLabel: string;
|
||||
localstorageId: string;
|
||||
localStorageId: string;
|
||||
}
|
||||
|
||||
const LabelContainer = styled.span`
|
||||
|
@ -30,10 +30,10 @@ const StyledBadge = styled(EuiBadge)`
|
|||
/**
|
||||
* Gets current state from local storage to show or hide the badge.
|
||||
* Default value: true
|
||||
* @param localstorageId
|
||||
* @param localStorageId
|
||||
*/
|
||||
function getBadgeVisibility(localstorageId: string) {
|
||||
const storedItem = window.localStorage.getItem(localstorageId);
|
||||
function getBadgeVisibility(localStorageId: string) {
|
||||
const storedItem = window.localStorage.getItem(localStorageId);
|
||||
if (storedItem) {
|
||||
return JSON.parse(storedItem) as boolean;
|
||||
}
|
||||
|
@ -43,20 +43,26 @@ function getBadgeVisibility(localstorageId: string) {
|
|||
|
||||
/**
|
||||
* Saves on local storage that this item should no longer be visible
|
||||
* @param localstorageId
|
||||
* @param localStorageId
|
||||
*/
|
||||
export function hideBadge(localstorageId: string) {
|
||||
window.localStorage.setItem(localstorageId, JSON.stringify(false));
|
||||
export function hideBadge(localStorageId: string) {
|
||||
window.localStorage.setItem(localStorageId, JSON.stringify(false));
|
||||
}
|
||||
|
||||
export function NavNameWithBadge({ label, badgeLabel, localstorageId }: Props) {
|
||||
const isBadgeVisible = getBadgeVisibility(localstorageId);
|
||||
export function NavNameWithBadge({ label, localStorageId }: Props) {
|
||||
const isBadgeVisible = getBadgeVisibility(localStorageId);
|
||||
return (
|
||||
<>
|
||||
<LabelContainer className="eui-textTruncate">
|
||||
<span>{label}</span>
|
||||
</LabelContainer>
|
||||
{isBadgeVisible && <StyledBadge color="accent">{badgeLabel}</StyledBadge>}
|
||||
{isBadgeVisible && (
|
||||
<StyledBadge color="accent">
|
||||
{i18n.translate('xpack.observability.navigation.newBadge', {
|
||||
defaultMessage: 'NEW',
|
||||
})}
|
||||
</StyledBadge>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -75,12 +75,8 @@ export function ObservabilityPageTemplate({
|
|||
const badgeLocalStorageId = `observability.nav_item_badge_visible_${entry.app}${entry.path}`;
|
||||
return {
|
||||
id: `${sectionIndex}.${entryIndex}`,
|
||||
name: entry.sideBadgeLabel ? (
|
||||
<NavNameWithBadge
|
||||
label={entry.label}
|
||||
badgeLabel={entry.sideBadgeLabel}
|
||||
localstorageId={badgeLocalStorageId}
|
||||
/>
|
||||
name: entry.isNewFeature ? (
|
||||
<NavNameWithBadge label={entry.label} localStorageId={badgeLocalStorageId} />
|
||||
) : (
|
||||
entry.label
|
||||
),
|
||||
|
@ -91,8 +87,8 @@ export function ObservabilityPageTemplate({
|
|||
entry.onClick(event);
|
||||
}
|
||||
|
||||
// When side badge is defined hides it when the item is clicked
|
||||
if (entry.sideBadgeLabel) {
|
||||
// Hides NEW badge when the item is clicked
|
||||
if (entry.isNewFeature) {
|
||||
hideBadge(badgeLocalStorageId);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ export interface NavigationEntry {
|
|||
ignoreTrailingSlash?: boolean;
|
||||
// handler to be called when the item is clicked
|
||||
onClick?: (event: React.MouseEvent<HTMLElement | HTMLButtonElement, MouseEvent>) => void;
|
||||
// the label of the badge that is shown besides the navigation label
|
||||
sideBadgeLabel?: string;
|
||||
// shows NEW badge besides the navigation label, which will automatically disappear when menu item is clicked.
|
||||
isNewFeature?: boolean;
|
||||
}
|
||||
|
||||
export interface NavigationRegistry {
|
||||
|
|
Loading…
Reference in a new issue