Skip to content

Commit

Permalink
Wires content management to UI. Mostly complete.
Browse files Browse the repository at this point in the history
  • Loading branch information
nickpeihl committed Jul 25, 2023
1 parent 9879a34 commit 6046fde
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ import { memoizedGetOrderedLinkList } from '../editor/navigation_embeddable_edit
export const NavigationEmbeddableComponent = () => {
const navEmbeddable = useNavigationEmbeddable();

const links = navEmbeddable.select((state) => state.output.links) ?? {};
const links = navEmbeddable.select((state) => state.output.attributes?.links);

const orderedLinks = useMemo(() => {
if (!links) return [];
return memoizedGetOrderedLinkList(links);
}, [links]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import { NavigationEmbeddablePanelEditorLink } from './navigation_embeddable_pan

import noLinksIllustrationDark from '../assets/empty_links_dark.svg';
import noLinksIllustrationLight from '../assets/empty_links_light.svg';

import './navigation_embeddable.scss';

const NavigationEmbeddablePanelEditor = ({
Expand All @@ -59,18 +58,19 @@ const NavigationEmbeddablePanelEditor = ({
savedObjectId,
parentDashboard,
}: {
onSave: (attributes: NavigationEmbeddableAttributes, useRefType: boolean) => void;
onSave: (newAttributes: NavigationEmbeddableAttributes, useRefType: boolean) => void;
onClose: () => void;
parentDashboard?: DashboardContainer;
attributes?: NavigationEmbeddableAttributes;
savedObjectId?: string;
parentDashboard?: DashboardContainer;
}) => {
const isDarkTheme = useObservable(coreServices.theme.theme$)?.darkMode;
const editLinkFlyoutRef: React.RefObject<HTMLDivElement> = useMemo(() => React.createRef(), []);

const [orderedLinks, setOrderedLinks] = useState<NavigationEmbeddableLink[]>([]);
const [saveToLibrary, setSaveToLibrary] = useState(false);
const [libraryTitle, setLibraryTitle] = useState<string | undefined>();
const [saveToLibrary, setSaveToLibrary] = useState(Boolean(savedObjectId));
const [libraryTitle, setLibraryTitle] = useState<string>(attributes?.title ?? '');
const [isSaving, setIsSaving] = useState(false);

useEffect(() => {
const initialLinks = attributes?.links;
Expand Down Expand Up @@ -133,15 +133,23 @@ const NavigationEmbeddablePanelEditor = ({
const button = (
<EuiButton
disabled={!canSave}
onClick={() => {
isLoading={isSaving}
onClick={async () => {
setIsSaving(true);
const newLinks = orderedLinks.reduce((prev, link, i) => {
return { ...prev, [link.id]: { ...link, order: i } };
}, {} as NavigationEmbeddableLinkList);
const newAttributes = { ...attributes, title: libraryTitle, links: newLinks };
onSave(newAttributes, !Boolean(savedObjectId));
const newAttributes: NavigationEmbeddableAttributes = {
title: libraryTitle,
links: newLinks,
};
await onSave(newAttributes, Boolean(savedObjectId) || saveToLibrary);
setIsSaving(false);
}}
>
{NavEmbeddableStrings.editor.panelEditor.getSaveButtonLabel()}
{savedObjectId
? NavEmbeddableStrings.editor.panelEditor.getUpdateLibraryItemButtonLabel()
: NavEmbeddableStrings.editor.panelEditor.getSaveButtonLabel()}
</EuiButton>
);

Expand All @@ -152,7 +160,7 @@ const NavigationEmbeddablePanelEditor = ({
{button}
</EuiToolTip>
);
}, [onSave, orderedLinks, attributes, saveToLibrary, libraryTitle, savedObjectId]);
}, [onSave, isSaving, orderedLinks, saveToLibrary, libraryTitle, savedObjectId]);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@ import {
} from '@elastic/eui';
import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container';

import {
NavigationLinkInfo,
DASHBOARD_LINK_TYPE,
NavigationEmbeddableLink,
} from '../embeddable/types';
import { NavigationLinkInfo } from '../embeddable/types';
import { DASHBOARD_LINK_TYPE, NavigationEmbeddableLink } from '../../common/content_management';
import { fetchDashboard } from './dashboard_link/dashboard_link_tools';
import { NavEmbeddableStrings } from './navigation_embeddable_strings';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ export const NavEmbeddableStrings = {
i18n.translate('navigationEmbeddable.panelEditor.saveButtonLabel', {
defaultMessage: 'Save',
}),
getSaveToLibraryButtonLabel: () =>
i18n.translate('navigationEmbeddable.panelEditor.saveToLibraryButtonLabel', {
defaultMessage: 'Save to library',
}),
getUpdateLibraryItemButtonLabel: () =>
i18n.translate('navigationEmbeddable.panelEditor.updateLibraryItemButtonLabel', {
defaultMessage: 'Update library item',
}),
getTitleInputLabel: () =>
i18n.translate('navigationEmbeddable.panelEditor.titleInputLabel', {
defaultMessage: 'Title',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ import { EuiLoadingSpinner, EuiPanel } from '@elastic/eui';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container';

import { NavigationEmbeddableAttributes } from '../../common/content_management';
import { coreServices } from '../services/kibana_services';
import { NavigationEmbeddableInput } from '../embeddable/types';
import {
NavigationEmbeddableByReferenceInput,
NavigationEmbeddableInput,
} from '../embeddable/types';
import { memoizedFetchDashboards } from '../components/dashboard_link/dashboard_link_tools';
import { getNavigationEmbeddableAttributeService } from '../services/attribute_service';
import { NavigationEmbeddableAttributes } from '../../common/content_management';

const LazyNavigationEmbeddablePanelEditor = React.lazy(
() => import('../components/navigation_embeddable_panel_editor')
Expand All @@ -43,15 +46,16 @@ export async function openEditorFlyout(
const { attributes } = await getNavigationEmbeddableAttributeService().unwrapAttributes(
initialInput
);

return new Promise((resolve, reject) => {
const closed$ = new Subject<true>();

const onSave = async (newAttributes: NavigationEmbeddableAttributes, useRefType: boolean) => {
const wrappedAttributes = (await getNavigationEmbeddableAttributeService()).wrapAttributes(
const newInput = await getNavigationEmbeddableAttributeService().wrapAttributes(
newAttributes,
useRefType
);
resolve(wrappedAttributes);
resolve(newInput);
editorFlyout.close();
};

Expand All @@ -76,6 +80,7 @@ export async function openEditorFlyout(
onClose={onCancel}
onSave={onSave}
parentDashboard={parentDashboard}
savedObjectId={(initialInput as NavigationEmbeddableByReferenceInput).savedObjectId}
/>,
{ theme$: coreServices.theme.theme$ }
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '@kbn/embeddable-plugin/public';
import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container';
import { ReduxEmbeddableTools, ReduxToolsPackage } from '@kbn/presentation-util-plugin/public';
import { Subscription } from 'rxjs';
import { navigationEmbeddableReducers } from './navigation_embeddable_reducers';
import {
NavigationEmbeddableByReferenceInput,
Expand Down Expand Up @@ -56,14 +57,17 @@ export class NavigationEmbeddable
public readonly type = NAVIGATION_EMBEDDABLE_TYPE;
deferEmbeddableLoad = true;

private attributes?: NavigationEmbeddableAttributes;
private savedObjectId?: string;
private subscriptions: Subscription = new Subscription();

// state management
public select: NavigationReduxEmbeddableTools['select'];
public getState: NavigationReduxEmbeddableTools['getState'];
public dispatch: NavigationReduxEmbeddableTools['dispatch'];
public onStateChange: NavigationReduxEmbeddableTools['onStateChange'];

private cleanupStateTools: () => void;
private attributes?: NavigationEmbeddableAttributes;

constructor(
reduxToolsPackage: ReduxToolsPackage,
Expand Down Expand Up @@ -96,6 +100,23 @@ export class NavigationEmbeddable
this.dispatch = reduxEmbeddableTools.dispatch;
this.cleanupStateTools = reduxEmbeddableTools.cleanup;
this.onStateChange = reduxEmbeddableTools.onStateChange;

this.subscriptions.add(
this.getInput$().subscribe(async () => {
const savedObjectId = (this.getInput() as NavigationEmbeddableByReferenceInput)
.savedObjectId;
const attributes = (this.getInput() as NavigationEmbeddableByValueInput).attributes;
if (this.attributes !== attributes || this.savedObjectId !== savedObjectId) {
this.savedObjectId = savedObjectId;
this.reload();
} else {
this.updateOutput({
attributes: this.attributes,
defaultTitle: this.attributes.title,
});
}
})
);
this.setInitializationFinished();
}

Expand All @@ -116,10 +137,12 @@ export class NavigationEmbeddable
}

public async reload() {
this.attributes = (await this.attributeService.unwrapAttributes(this.input)).attributes;

this.updateOutput({
defaultTitle: this.attributes?.title,
defaultDescription: this.attributes?.description,
links: this.attributes?.links,
attributes: this.attributes,
defaultTitle: this.attributes.title,
defaultDescription: this.attributes.description,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import { lazyLoadReduxToolsPackage } from '@kbn/presentation-util-plugin/public'
import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container';

import { EmbeddablePersistableStateService } from '@kbn/embeddable-plugin/common';
import { NavigationEmbeddableByReferenceInput, NavigationEmbeddableInput } from './types';
import {
NavigationEmbeddableByReferenceInput,
NavigationEmbeddableByValueInput,
NavigationEmbeddableInput,
} from './types';
import type { NavigationEmbeddable } from './navigation_embeddable';
import { coreServices, untilPluginStartServicesReady } from '../services/kibana_services';
import { getNavigationEmbeddableAttributeService } from '../services/attribute_service';
Expand Down Expand Up @@ -78,10 +82,14 @@ export class NavigationEmbeddableFactoryDefinition
if (!(input as NavigationEmbeddableByReferenceInput).savedObjectId) {
(input as NavigationEmbeddableByReferenceInput).savedObjectId = savedObjectId;
}
return this.create(input, parent);
return this.create(input, parent, savedObjectId);
}

public async create(initialInput: NavigationEmbeddableInput, parent: DashboardContainer) {
public async create(
initialInput: NavigationEmbeddableInput,
parent: DashboardContainer,
savedObjectId?: string
) {
await untilPluginStartServicesReady();

const reduxEmbeddablePackage = await lazyLoadReduxToolsPackage();
Expand All @@ -106,7 +114,10 @@ export class NavigationEmbeddableFactoryDefinition
const { openEditorFlyout } = await import('../editor/open_editor_flyout');

const input = await openEditorFlyout(
{ ...getDefaultNavigationEmbeddableInput(), ...initialInput },
{
...getDefaultNavigationEmbeddableInput(),
...initialInput,
} as NavigationEmbeddableByValueInput,
parent
).catch(() => {
// swallow the promise rejection that happens when the flyout is closed
Expand Down
3 changes: 1 addition & 2 deletions src/plugins/navigation_embeddable/public/embeddable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
EXTERNAL_LINK_TYPE,
NavigationLinkType,
NavigationEmbeddableAttributes,
NavigationEmbeddableLinkList,
} from '../../common/content_management';

export const NavigationLinkInfo: {
Expand Down Expand Up @@ -49,7 +48,7 @@ export type NavigationEmbeddableInput =
| NavigationEmbeddableByReferenceInput;

export type NavigationEmbeddableOutput = EmbeddableOutput & {
links?: NavigationEmbeddableLinkList;
attributes?: NavigationEmbeddableAttributes;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { embeddableService } from './kibana_services';
import { navigationEmbeddableClient } from '../content_management';
import { NAVIGATION_EMBEDDABLE_TYPE } from '../../common/constants';

type NavigationEmbeddableDocument = NavigationEmbeddableAttributes & {
export type NavigationEmbeddableDocument = NavigationEmbeddableAttributes & {
references?: Reference[];
};

Expand Down

0 comments on commit 6046fde

Please sign in to comment.