mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Remove chrome.navLinks.update
(#99633)
This commit is contained in:
parent
9793a8fefb
commit
c9f7ab3f72
19 changed files with 50 additions and 203 deletions
|
@ -23,5 +23,4 @@ export interface ChromeNavLinks
|
|||
| [getNavLinks$()](./kibana-plugin-core-public.chromenavlinks.getnavlinks_.md) | Get an observable for a sorted list of navlinks. |
|
||||
| [has(id)](./kibana-plugin-core-public.chromenavlinks.has.md) | Check whether or not a navlink exists. |
|
||||
| [showOnly(id)](./kibana-plugin-core-public.chromenavlinks.showonly.md) | Remove all navlinks except the one matching the given id. |
|
||||
| [update(id, values)](./kibana-plugin-core-public.chromenavlinks.update.md) | Update the navlink for the given id with the updated attributes. Returns the updated navlink or <code>undefined</code> if it does not exist. |
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeNavLinks](./kibana-plugin-core-public.chromenavlinks.md) > [update](./kibana-plugin-core-public.chromenavlinks.update.md)
|
||||
|
||||
## ChromeNavLinks.update() method
|
||||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Uses the property when registering your application with [ApplicationSetup.register()](./kibana-plugin-core-public.applicationsetup.register.md) instead.
|
||||
>
|
||||
|
||||
Update the navlink for the given id with the updated attributes. Returns the updated navlink or `undefined` if it does not exist.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
update(id: string, values: ChromeNavLinkUpdateableFields): ChromeNavLink | undefined;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| id | <code>string</code> | |
|
||||
| values | <code>ChromeNavLinkUpdateableFields</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`ChromeNavLink | undefined`
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeNavLinkUpdateableFields](./kibana-plugin-core-public.chromenavlinkupdateablefields.md)
|
||||
|
||||
## ChromeNavLinkUpdateableFields type
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export declare type ChromeNavLinkUpdateableFields = Partial<Pick<ChromeNavLink, 'disabled' | 'hidden' | 'url' | 'href'>>;
|
||||
```
|
|
@ -154,7 +154,6 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
|
|||
| [ChromeBreadcrumb](./kibana-plugin-core-public.chromebreadcrumb.md) | |
|
||||
| [ChromeHelpExtensionLinkBase](./kibana-plugin-core-public.chromehelpextensionlinkbase.md) | |
|
||||
| [ChromeHelpExtensionMenuLink](./kibana-plugin-core-public.chromehelpextensionmenulink.md) | |
|
||||
| [ChromeNavLinkUpdateableFields](./kibana-plugin-core-public.chromenavlinkupdateablefields.md) | |
|
||||
| [FatalErrorsStart](./kibana-plugin-core-public.fatalerrorsstart.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. |
|
||||
| [HttpStart](./kibana-plugin-core-public.httpstart.md) | See [HttpSetup](./kibana-plugin-core-public.httpsetup.md) |
|
||||
| [IToasts](./kibana-plugin-core-public.itoasts.md) | Methods for adding and removing global toast messages. See [ToastsApi](./kibana-plugin-core-public.toastsapi.md)<!-- -->. |
|
||||
|
|
|
@ -20,7 +20,6 @@ const createStartContractMock = () => {
|
|||
get: jest.fn(),
|
||||
getAll: jest.fn(),
|
||||
showOnly: jest.fn(),
|
||||
update: jest.fn(),
|
||||
enableForcedAppSwitcherNavigation: jest.fn(),
|
||||
getForceAppSwitcherNavigation$: jest.fn(),
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@ export type {
|
|||
ChromeHelpExtensionMenuGitHubLink,
|
||||
} from './ui/header/header_help_menu';
|
||||
export type { NavType } from './ui';
|
||||
export type { ChromeNavLink, ChromeNavLinks, ChromeNavLinkUpdateableFields } from './nav_links';
|
||||
export type { ChromeNavLink, ChromeNavLinks } from './nav_links';
|
||||
export type {
|
||||
ChromeRecentlyAccessed,
|
||||
ChromeRecentlyAccessedHistoryItem,
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
*/
|
||||
export { NavLinksService } from './nav_links_service';
|
||||
|
||||
export type { ChromeNavLink, ChromeNavLinkUpdateableFields } from './nav_link';
|
||||
export type { ChromeNavLink } from './nav_link';
|
||||
export type { ChromeNavLinks } from './nav_links_service';
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { pick } from '@kbn/std';
|
||||
import { AppCategory } from '../../';
|
||||
|
||||
/**
|
||||
|
@ -81,11 +80,6 @@ export interface ChromeNavLink {
|
|||
readonly hidden?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export type ChromeNavLinkUpdateableFields = Partial<
|
||||
Pick<ChromeNavLink, 'disabled' | 'hidden' | 'url' | 'href'>
|
||||
>;
|
||||
|
||||
export class NavLinkWrapper {
|
||||
public readonly id: string;
|
||||
public readonly properties: Readonly<ChromeNavLink>;
|
||||
|
@ -98,10 +92,4 @@ export class NavLinkWrapper {
|
|||
this.id = properties.id;
|
||||
this.properties = Object.freeze(properties);
|
||||
}
|
||||
|
||||
public update(newProps: ChromeNavLinkUpdateableFields) {
|
||||
// Enforce limited properties at runtime for JS code
|
||||
newProps = pick(newProps, ['disabled', 'hidden', 'url', 'href']);
|
||||
return new NavLinkWrapper({ ...this.properties, ...newProps });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,13 +73,10 @@ describe('NavLinksService', () => {
|
|||
const navLinkIds$ = start.getNavLinks$().pipe(map((links) => links.map((l) => l.id)));
|
||||
const emittedLinks: string[][] = [];
|
||||
navLinkIds$.subscribe((r) => emittedLinks.push(r));
|
||||
start.update('app1', { href: '/foo' });
|
||||
start.showOnly('app1');
|
||||
|
||||
service.stop();
|
||||
expect(emittedLinks).toEqual([
|
||||
['app2', 'app1'],
|
||||
['app2', 'app1'],
|
||||
]);
|
||||
expect(emittedLinks).toEqual([['app2', 'app1'], ['app1']]);
|
||||
});
|
||||
|
||||
it('completes when service is stopped', async () => {
|
||||
|
@ -170,45 +167,6 @@ describe('NavLinksService', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('#update()', () => {
|
||||
it('updates the navlinks and returns the updated link', async () => {
|
||||
expect(start.update('app2', { hidden: true })).toEqual(
|
||||
expect.objectContaining({
|
||||
hidden: true,
|
||||
id: 'app2',
|
||||
order: -10,
|
||||
title: 'App 2',
|
||||
euiIconType: 'canvasApp',
|
||||
})
|
||||
);
|
||||
const hiddenLinkIds = await start
|
||||
.getNavLinks$()
|
||||
.pipe(
|
||||
take(1),
|
||||
map((links) => links.filter((l) => l.hidden).map((l) => l.id))
|
||||
)
|
||||
.toPromise();
|
||||
expect(hiddenLinkIds).toEqual(['app2']);
|
||||
});
|
||||
|
||||
it('returns undefined if link does not exist', () => {
|
||||
expect(start.update('fake', { hidden: true })).toBeUndefined();
|
||||
});
|
||||
|
||||
it('keeps the updated link when availableApps are re-emitted', async () => {
|
||||
start.update('app2', { hidden: true });
|
||||
mockAppService.applications$.next(mockAppService.applications$.value);
|
||||
const hiddenLinkIds = await start
|
||||
.getNavLinks$()
|
||||
.pipe(
|
||||
take(1),
|
||||
map((links) => links.filter((l) => l.hidden).map((l) => l.id))
|
||||
)
|
||||
.toPromise();
|
||||
expect(hiddenLinkIds).toEqual(['app2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#enableForcedAppSwitcherNavigation()', () => {
|
||||
it('flips #getForceAppSwitcherNavigation$()', async () => {
|
||||
await expect(start.getForceAppSwitcherNavigation$().pipe(take(1)).toPromise()).resolves.toBe(
|
||||
|
|
|
@ -12,7 +12,7 @@ import { map, takeUntil } from 'rxjs/operators';
|
|||
|
||||
import { InternalApplicationStart } from '../../application';
|
||||
import { HttpStart } from '../../http';
|
||||
import { ChromeNavLink, ChromeNavLinkUpdateableFields, NavLinkWrapper } from './nav_link';
|
||||
import { ChromeNavLink, NavLinkWrapper } from './nav_link';
|
||||
import { toNavLink } from './to_nav_link';
|
||||
|
||||
interface StartDeps {
|
||||
|
@ -58,18 +58,6 @@ export interface ChromeNavLinks {
|
|||
*/
|
||||
showOnly(id: string): void;
|
||||
|
||||
/**
|
||||
* Update the navlink for the given id with the updated attributes.
|
||||
* Returns the updated navlink or `undefined` if it does not exist.
|
||||
*
|
||||
* @deprecated Uses the {@link AppBase.updater$} property when registering
|
||||
* your application with {@link ApplicationSetup.register} instead.
|
||||
*
|
||||
* @param id
|
||||
* @param values
|
||||
*/
|
||||
update(id: string, values: ChromeNavLinkUpdateableFields): ChromeNavLink | undefined;
|
||||
|
||||
/**
|
||||
* Enable forced navigation mode, which will trigger a page refresh
|
||||
* when a nav link is clicked and only the hash is updated.
|
||||
|
@ -109,6 +97,7 @@ export class NavLinksService {
|
|||
// now that availableApps$ is an observable, we need to keep record of all
|
||||
// manual link modifications to be able to re-apply then after every
|
||||
// availableApps$ changes.
|
||||
// Only in use by `showOnly` API, can be removed once dashboard_mode is removed in 8.0
|
||||
const linkUpdaters$ = new BehaviorSubject<LinksUpdater[]>([]);
|
||||
const navLinks$ = new BehaviorSubject<ReadonlyMap<string, NavLinkWrapper>>(new Map());
|
||||
|
||||
|
@ -153,25 +142,6 @@ export class NavLinksService {
|
|||
linkUpdaters$.next([...linkUpdaters$.value, updater]);
|
||||
},
|
||||
|
||||
update(id: string, values: ChromeNavLinkUpdateableFields) {
|
||||
if (!this.has(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updater: LinksUpdater = (navLinks) =>
|
||||
new Map(
|
||||
[...navLinks.entries()].map(([linkId, link]) => {
|
||||
return [linkId, link.id === id ? link.update(values) : link] as [
|
||||
string,
|
||||
NavLinkWrapper
|
||||
];
|
||||
})
|
||||
);
|
||||
|
||||
linkUpdaters$.next([...linkUpdaters$.value, updater]);
|
||||
return this.get(id);
|
||||
},
|
||||
|
||||
enableForcedAppSwitcherNavigation() {
|
||||
forceAppSwitcherNavigation$.next(true);
|
||||
},
|
||||
|
|
|
@ -41,7 +41,6 @@ import {
|
|||
ChromeNavControls,
|
||||
ChromeNavLink,
|
||||
ChromeNavLinks,
|
||||
ChromeNavLinkUpdateableFields,
|
||||
ChromeDocTitle,
|
||||
ChromeStart,
|
||||
ChromeRecentlyAccessed,
|
||||
|
@ -298,7 +297,6 @@ export type {
|
|||
ChromeNavControls,
|
||||
ChromeNavLink,
|
||||
ChromeNavLinks,
|
||||
ChromeNavLinkUpdateableFields,
|
||||
ChromeDocTitle,
|
||||
ChromeRecentlyAccessed,
|
||||
ChromeRecentlyAccessedHistoryItem,
|
||||
|
|
|
@ -332,15 +332,8 @@ export interface ChromeNavLinks {
|
|||
getNavLinks$(): Observable<Array<Readonly<ChromeNavLink>>>;
|
||||
has(id: string): boolean;
|
||||
showOnly(id: string): void;
|
||||
// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "AppBase"
|
||||
//
|
||||
// @deprecated
|
||||
update(id: string, values: ChromeNavLinkUpdateableFields): ChromeNavLink | undefined;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export type ChromeNavLinkUpdateableFields = Partial<Pick<ChromeNavLink, 'disabled' | 'hidden' | 'url' | 'href'>>;
|
||||
|
||||
// @public
|
||||
export interface ChromeRecentlyAccessed {
|
||||
// Warning: (ae-unresolved-link) The @link reference could not be resolved: No member was found with name "basePath"
|
||||
|
|
|
@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import type { ConfigSchema } from '.';
|
||||
import {
|
||||
AppMountParameters,
|
||||
AppNavLinkStatus,
|
||||
CoreSetup,
|
||||
CoreStart,
|
||||
DEFAULT_APP_CATEGORIES,
|
||||
|
@ -40,7 +41,6 @@ import type {
|
|||
} from '../../triggers_actions_ui/public';
|
||||
import { registerApmAlerts } from './components/alerting/register_apm_alerts';
|
||||
import { featureCatalogueEntry } from './featureCatalogueEntry';
|
||||
import { toggleAppLinkInNav } from './toggleAppLinkInNav';
|
||||
|
||||
export type ApmPluginSetup = ReturnType<ApmPlugin['setup']>;
|
||||
|
||||
|
@ -193,6 +193,9 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
|
|||
order: 8500,
|
||||
euiIconType: 'logoObservability',
|
||||
category: DEFAULT_APP_CATEGORIES.observability,
|
||||
navLinkStatus: config.ui.enabled
|
||||
? AppNavLinkStatus.default
|
||||
: AppNavLinkStatus.hidden,
|
||||
meta: {
|
||||
keywords: [
|
||||
'RUM',
|
||||
|
@ -231,7 +234,5 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
|
|||
|
||||
return {};
|
||||
}
|
||||
public start(core: CoreStart, plugins: ApmPluginStartDeps) {
|
||||
toggleAppLinkInNav(core, this.initializerContext.config.get());
|
||||
}
|
||||
public start(core: CoreStart, plugins: ApmPluginStartDeps) {}
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CoreStart } from 'kibana/public';
|
||||
import { ConfigSchema } from '.';
|
||||
|
||||
export function toggleAppLinkInNav(core: CoreStart, { ui }: ConfigSchema) {
|
||||
if (ui.enabled === false) {
|
||||
core.chrome.navLinks.update('apm', { hidden: true });
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ export function assertNever(x: never): never {
|
|||
export interface GraphLicenseInformation {
|
||||
showAppLink: boolean;
|
||||
enableAppLink: boolean;
|
||||
message: string;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export function checkLicense(license: ILicense | undefined): GraphLicenseInformation {
|
||||
|
@ -53,20 +53,19 @@ export function checkLicense(license: ILicense | undefined): GraphLicenseInforma
|
|||
return {
|
||||
showAppLink: true,
|
||||
enableAppLink: false,
|
||||
message: check.message || '',
|
||||
message: check.message,
|
||||
};
|
||||
case 'invalid':
|
||||
case 'unavailable':
|
||||
return {
|
||||
showAppLink: false,
|
||||
enableAppLink: false,
|
||||
message: check.message || '',
|
||||
message: check.message,
|
||||
};
|
||||
case 'valid':
|
||||
return {
|
||||
showAppLink: true,
|
||||
enableAppLink: true,
|
||||
message: '',
|
||||
};
|
||||
default:
|
||||
return assertNever(check.state);
|
||||
|
|
|
@ -91,7 +91,10 @@ export const renderApp = ({ appBasePath, element, kibanaLegacy, ...deps }: Graph
|
|||
const licenseAllowsToShowThisPage = info.showAppLink && info.enableAppLink;
|
||||
|
||||
if (!licenseAllowsToShowThisPage) {
|
||||
deps.core.notifications.toasts.addDanger(info.message);
|
||||
if (info.message) {
|
||||
deps.core.notifications.toasts.addDanger(info.message);
|
||||
}
|
||||
|
||||
// This has to happen in the next tick because otherwise the original navigation
|
||||
// bringing us to the graph app in the first place
|
||||
// never completes and the browser enters are redirect loop
|
||||
|
|
|
@ -6,9 +6,17 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreSetup, CoreStart } from 'kibana/public';
|
||||
import { AppMountParameters, Plugin } from 'src/core/public';
|
||||
import { PluginInitializerContext } from 'kibana/public';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import {
|
||||
AppNavLinkStatus,
|
||||
AppUpdater,
|
||||
CoreSetup,
|
||||
CoreStart,
|
||||
AppMountParameters,
|
||||
Plugin,
|
||||
PluginInitializerContext,
|
||||
DEFAULT_APP_CATEGORIES,
|
||||
} from '../../../../src/core/public';
|
||||
|
||||
import { Storage } from '../../../../src/plugins/kibana_utils/public';
|
||||
import {
|
||||
|
@ -18,7 +26,6 @@ import {
|
|||
import { NavigationPublicPluginStart as NavigationStart } from '../../../../src/plugins/navigation/public';
|
||||
import { DataPublicPluginStart } from '../../../../src/plugins/data/public';
|
||||
|
||||
import { toggleNavLink } from './services/toggle_nav_link';
|
||||
import { LicensingPluginStart } from '../../licensing/public';
|
||||
import { checkLicense } from '../common/check_license';
|
||||
import {
|
||||
|
@ -26,7 +33,6 @@ import {
|
|||
HomePublicPluginSetup,
|
||||
HomePublicPluginStart,
|
||||
} from '../../../../src/plugins/home/public';
|
||||
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
|
||||
import { ConfigSchema } from '../config';
|
||||
import { SavedObjectsStart } from '../../../../src/plugins/saved_objects/public';
|
||||
|
||||
|
@ -45,6 +51,8 @@ export interface GraphPluginStartDependencies {
|
|||
|
||||
export class GraphPlugin
|
||||
implements Plugin<void, void, GraphPluginSetupDependencies, GraphPluginStartDependencies> {
|
||||
private readonly appUpdater$ = new BehaviorSubject<AppUpdater>(() => ({}));
|
||||
|
||||
constructor(private initializerContext: PluginInitializerContext<ConfigSchema>) {}
|
||||
|
||||
setup(core: CoreSetup<GraphPluginStartDependencies>, { home }: GraphPluginSetupDependencies) {
|
||||
|
@ -77,6 +85,7 @@ export class GraphPlugin
|
|||
appRoute: '/app/graph',
|
||||
euiIconType: 'logoKibana',
|
||||
category: DEFAULT_APP_CATEGORIES.kibana,
|
||||
updater$: this.appUpdater$,
|
||||
mount: async (params: AppMountParameters) => {
|
||||
const [coreStart, pluginsStart] = await core.getStartServices();
|
||||
coreStart.chrome.docTitle.change(
|
||||
|
@ -112,7 +121,16 @@ export class GraphPlugin
|
|||
start(core: CoreStart, { home, licensing }: GraphPluginStartDependencies) {
|
||||
licensing.license$.subscribe((license) => {
|
||||
const licenseInformation = checkLicense(license);
|
||||
toggleNavLink(licenseInformation, core.chrome.navLinks);
|
||||
|
||||
this.appUpdater$.next(() => ({
|
||||
navLinkStatus: licenseInformation.showAppLink
|
||||
? licenseInformation.enableAppLink
|
||||
? AppNavLinkStatus.visible
|
||||
: AppNavLinkStatus.disabled
|
||||
: AppNavLinkStatus.hidden,
|
||||
tooltip: licenseInformation.showAppLink ? licenseInformation.message : undefined,
|
||||
}));
|
||||
|
||||
if (home && !licenseInformation.enableAppLink) {
|
||||
home.featureCatalogue.removeFeature('graph');
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ChromeNavLink, ChromeNavLinks } from 'kibana/public';
|
||||
import { GraphLicenseInformation } from '../../common/check_license';
|
||||
|
||||
type Mutable<T> = { -readonly [P in keyof T]: T[P] };
|
||||
type ChromeNavLinkUpdate = Mutable<Partial<ChromeNavLink>>;
|
||||
|
||||
export function toggleNavLink(
|
||||
licenseInformation: GraphLicenseInformation,
|
||||
navLinks: ChromeNavLinks
|
||||
) {
|
||||
const navLinkUpdates: ChromeNavLinkUpdate = {
|
||||
hidden: !licenseInformation.showAppLink,
|
||||
};
|
||||
if (licenseInformation.showAppLink) {
|
||||
navLinkUpdates.disabled = !licenseInformation.enableAppLink;
|
||||
navLinkUpdates.tooltip = licenseInformation.message;
|
||||
}
|
||||
|
||||
navLinks.update('graph', navLinkUpdates);
|
||||
}
|
|
@ -84,13 +84,19 @@ class MyPlugin {
|
|||
import { LicensingPluginSetup } from '../licensing/public'
|
||||
class MyPlugin {
|
||||
setup(core: CoreSetup, deps: SetupDeps) {
|
||||
const appUpdater$ = new BehaviorSubject<AppUpdater>(() => {});
|
||||
core.application.register({
|
||||
id: 'myApp',
|
||||
updater$: appUpdater$,
|
||||
});
|
||||
|
||||
deps.licensing.license$.subscribe(license => {
|
||||
const { state, message } = license.check('myPlugin', 'gold')
|
||||
const hasRequiredLicense = state === 'valid';
|
||||
const showLinks = hasRequiredLicense && license.getFeature('name').isAvailable;
|
||||
|
||||
chrome.navLinks.update('myPlugin', {
|
||||
hidden: !showLinks
|
||||
appUpdater$.next(() => {
|
||||
navLinkStatus: showLinks ? AppNavLinkStatus.visible : AppNavLinkStatus.hidden
|
||||
});
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue