Skip to content

Commit

Permalink
start to converge into new implementation across usages of the share …
Browse files Browse the repository at this point in the history
…plugin
  • Loading branch information
eokoneyo committed Feb 18, 2025
1 parent b7f0a0f commit c6a9183
Show file tree
Hide file tree
Showing 15 changed files with 387 additions and 453 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ export function ShowShareModal({
),
},
embed: {
embedUrlParamExtensions: [
{
paramName: 'embed',
component: EmbedUrlParamExtension,
},
],
draftModeCallOut: (
<EuiCallOut
color="warning"
Expand Down Expand Up @@ -261,12 +267,6 @@ export function ShowShareModal({
params: locatorParams,
},
},
embedUrlParamExtensions: [
{
paramName: 'embed',
component: EmbedUrlParamExtension,
},
],
snapshotShareWarning: Boolean(unsavedDashboardState?.panels)
? shareModalStrings.getSnapshotShareWarning()
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,16 @@ import { I18nStart } from '@kbn/core/public';
import React, { type PropsWithChildren, createContext, useContext } from 'react';

import { AnonymousAccessServiceContract } from '../../../common';
import type {
ShareMenuItemV2,
UrlParamExtension,
BrowserUrlService,
ShareContext,
} from '../../types';
import type { ShareTypes } from '../../services/share_orchestrator';
import type { ShareConfigs, BrowserUrlService, ShareContext, ShareTypes } from '../../types';

export type { ShareMenuItemV2, ShareContextObjectTypeConfig } from '../../types';
export type { ShareMenuItemV2 } from '../../types';

export interface IShareContext extends ShareContext {
allowEmbed: boolean;
allowShortUrl: boolean;
shareMenuItems: ShareMenuItemV2[];
embedUrlParamExtensions?: UrlParamExtension[];
shareMenuItems: ShareConfigs[];
anonymousAccess?: AnonymousAccessServiceContract;
urlService: BrowserUrlService;
snapshotShareWarning?: string;
theme: ThemeServiceSetup;
i18n: I18nStart;
publicAPIEnabled?: boolean;
Expand Down Expand Up @@ -57,19 +49,23 @@ export const useShareTabsContext = <T extends ShareTypes>(
);
}

const { shareMenuItems, ...rest } = context;
const { shareMenuItems, objectTypeMeta, ...rest } = context;

let shareTypeImplementations = shareMenuItems;

if (shareType) {
// only integration share types can have multiple implementations
shareTypeImplementations = (
shareType === 'integration' ? Array.prototype.filter : Array.prototype.find
).call(shareMenuItems, (item) => item.shareType === shareType && item.groupId === groupId);
).call(shareMenuItems, (item) => item.shareType === shareType && item?.groupId === groupId);
}

return {
...rest,
objectTypeMeta: {
...objectTypeMeta,
config: shareType ? objectTypeMeta.config[shareType] : objectTypeMeta.config,
},
shareMenuItems: shareTypeImplementations,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
EuiToolTip,
type EuiRadioGroupOption,
} from '@elastic/eui';
import { SupportedExportTypes, ShareMenuItemV2 } from '../../../types';
import { ShareMenuItemV2 } from '../../../types';
import { type IShareContext } from '../../context';

type ExportProps = Pick<IShareContext, 'isDirty' | 'objectId' | 'objectType' | 'onClose'> & {
Expand Down Expand Up @@ -58,9 +58,7 @@ const ExportContentUi = ({
}, []);
}, [aggregateReportTypes]);

const [selectedRadio, setSelectedRadio] = useState<SupportedExportTypes>(
radioOptions[0].id as SupportedExportTypes
);
const [selectedRadio, setSelectedRadio] = useState(radioOptions[0].id);

const {
config: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ const LinkTabContent: ILinkTab['content'] = ({ state, dispatch }) => {
shareableUrlLocatorParams,
allowShortUrl,
shareMenuItems,
delegatedShareUrlHandler,
} = useShareTabsContext('link');

const setDashboardLink = useCallback(
Expand Down Expand Up @@ -87,7 +86,7 @@ const LinkTabContent: ILinkTab['content'] = ({ state, dispatch }) => {
<LinkContent
{...{
objectType,
objectConfig: objectTypeMeta?.config?.link,
objectConfig: objectTypeMeta?.config,
objectId,
isDirty,
shareableUrl,
Expand All @@ -99,7 +98,6 @@ const LinkTabContent: ILinkTab['content'] = ({ state, dispatch }) => {
setIsNotSaved,
allowShortUrl,
setIsClicked: state?.setIsClicked,
delegatedShareUrlHandler,
}}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { useCallback, useState, useRef, useEffect } from 'react';
import type { IShareContext, ShareContextObjectTypeConfig } from '../../context';
import type { LinkShare } from '../../../services/share_orchestrator';
import type { LinkShare } from '../../../types';

type LinkProps = Pick<
IShareContext,
| 'objectType'
| 'objectId'
| 'isDirty'
| 'shareableUrl'
| 'delegatedShareUrlHandler'
| 'shareableUrlLocatorParams'
| 'allowShortUrl'
> & {
Expand All @@ -46,12 +45,11 @@ interface UrlParams {
export const LinkContent = ({
isDirty,
objectType,
objectConfig = {},
objectConfig,
shareableUrl,
shortUrlService,
shareableUrlLocatorParams,
allowShortUrl,
delegatedShareUrlHandler,
}: LinkProps) => {
const [snapshotUrl, setSnapshotUrl] = useState<string>('');
const [isTextCopied, setTextCopied] = useState(false);
Expand All @@ -60,6 +58,8 @@ export const LinkContent = ({
const urlToCopy = useRef<string | undefined>(undefined);
const copiedTextToolTipCleanupIdRef = useRef<ReturnType<typeof setTimeout>>();

const { delegatedShareUrlHandler } = objectConfig;

const getUrlWithUpdatedParams = useCallback((tempUrl: string): string => {
const urlWithUpdatedParams = urlParamsRef.current
? Object.keys(urlParamsRef.current).reduce((urlAccumulator, key) => {
Expand Down
27 changes: 14 additions & 13 deletions src/platform/plugins/shared/share/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import './index.scss';

import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
import { ShareMenuManager, ShareMenuManagerStart } from './services';
import { ShareMenuRegistry, ShareMenuRegistrySetup } from './services';
import { ShareOptionsManager } from './services/share_options_manager';
import { ShareRegistry /* , ShareMenuRegistrySetup */ } from './services';
import { UrlService } from '../common/url_service';
import { RedirectManager } from './url_service';
import type { RedirectOptions } from '../common/url_service/locators/redirect';
Expand All @@ -28,7 +27,7 @@ import { registrations } from './lib/registrations';
import type { BrowserUrlService } from './types';

/** @public */
export type SharePublicSetup = ShareMenuRegistrySetup & {
export interface SharePublicSetup {
/**
* Utilities to work with URL locators and short URLs.
*/
Expand All @@ -45,8 +44,12 @@ export type SharePublicSetup = ShareMenuRegistrySetup & {
*/
setAnonymousAccessServiceProvider: (provider: () => AnonymousAccessServiceContract) => void;

registerShareIntegration: ShareOptionsManager['registerShareIntegration'];
};
registerShareIntegration: ShareRegistry['registerShareIntegration'];
/**
* @deprecated Use `registerShareIntegration` instead.
*/
register: ShareRegistry['register'];
}

/** @public */
export type SharePublicStart = ShareMenuManagerStart & {
Expand Down Expand Up @@ -77,8 +80,7 @@ export class SharePlugin
SharePublicStartDependencies
>
{
private readonly shareMenuRegistry?: ShareMenuRegistry = new ShareMenuRegistry();
private readonly shareOptionsManager = new ShareOptionsManager();
private readonly shareRegistry = new ShareRegistry();
private readonly shareContextMenu = new ShareMenuManager();
private redirectManager?: RedirectManager;
private url?: BrowserUrlService;
Expand Down Expand Up @@ -128,10 +130,10 @@ export class SharePlugin
registrations.setup({ analytics });

return {
registerShareIntegration: this.shareOptionsManager.registerShareIntegration.bind(
this.shareOptionsManager
registerShareIntegration: this.shareRegistry.registerShareIntegration.bind(
this.shareRegistry
),
...this.shareMenuRegistry!.setup(),
register: this.shareRegistry.register.bind(this.shareRegistry),
url: this.url,
navigate: (options: RedirectOptions) => this.redirectManager!.navigate(options),
setAnonymousAccessServiceProvider: (provider: () => AnonymousAccessServiceContract) => {
Expand All @@ -146,16 +148,15 @@ export class SharePlugin
public start(core: CoreStart): SharePublicStart {
const disableEmbed = this.initializerContext.env.packageInfo.buildFlavor === 'serverless';

this.shareOptionsManager.start({
this.shareRegistry.start({
urlService: this.url!,
anonymousAccessServiceProvider: () => this.anonymousAccessServiceProvider!(),
});

const sharingContextMenuStart = this.shareContextMenu.start({
core,
shareRegistry: this.shareMenuRegistry!.start(),
shareRegistry: this.shareRegistry,
disableEmbed,
shareOptionsManager: this.shareOptionsManager,
});

return {
Expand Down
1 change: 0 additions & 1 deletion src/platform/plugins/shared/share/public/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@

export * from './share_menu_registry';
export * from './share_menu_manager';
export * from './share_options_manager';
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,23 @@ import ReactDOM from 'react-dom';
import { toMountPoint } from '@kbn/react-kibana-mount';
import { CoreStart, ThemeServiceStart, UserProfileService } from '@kbn/core/public';
import { ShowShareMenuOptions } from '../types';
import { ShareMenuRegistryStart } from './share_menu_registry';
import type { ShareMenuItemV2 } from '../types';
import { ShareRegistry } from './share_menu_registry';
import type { ShareConfigs } from '../types';
import { ShareMenu } from '../components/share_tabs';
import { ShareOptionsManager } from './share_options_manager';

interface ShareMenuManagerStartDeps {
core: CoreStart;
shareRegistry: ShareMenuRegistryStart;
shareRegistry: ShareRegistry;
disableEmbed: boolean;
shareOptionsManager: ShareOptionsManager;
}

export class ShareMenuManager {
private isOpen = false;
private shareOptionsManager?: ShareOptionsManager;
private shareRegistry?: ShareRegistry;
private container = document.createElement('div');

start({ core, shareOptionsManager, shareRegistry, disableEmbed }: ShareMenuManagerStartDeps) {
this.shareOptionsManager = shareOptionsManager;
start({ core, shareRegistry, disableEmbed }: ShareMenuManagerStartDeps) {
this.shareRegistry = shareRegistry;

return {
showShareDialog: this.showShareDialog.bind(this),
Expand All @@ -46,14 +44,14 @@ export class ShareMenuManager {
options.onClose?.();
};

const menuItems = this.shareOptionsManager!.resolveShareItemsForShareContext({
const menuItems = this.shareRegistry!.resolveShareItemsForShareContext({
...options,
onClose,
});

this.toggleShareContextMenu({
...options,
allowEmbed: disableEmbed ? false : options.allowEmbed,
allowEmbed: false, // disableEmbed ? false : options.allowEmbed,
onClose,
menuItems,
publicAPIEnabled: !disableEmbed,
Expand All @@ -68,16 +66,6 @@ export class ShareMenuManager {
this.isOpen = false;
};

private showShareDialog(app: string) {
const shareOptions = this.shareOptionsManager?.getShareConfigOptionsForApp(app);

if (!shareOptions) {
return;
}

console.log('share options available for app', shareOptions);
}

private toggleShareContextMenu({
anchorElement,
allowEmbed,
Expand All @@ -89,18 +77,14 @@ export class ShareMenuManager {
menuItems,
shareableUrl,
shareableUrlLocatorParams,
embedUrlParamExtensions,
showPublicUrlSwitch,
snapshotShareWarning,
onClose,
disabledShareUrl,
isDirty,
delegatedShareUrlHandler,
publicAPIEnabled,
...startServices
}: ShowShareMenuOptions & {
anchorElement: HTMLElement;
menuItems: ShareMenuItemV2[];
menuItems: ShareConfigs[];
onClose: () => void;
isDirty: boolean;
userProfile: UserProfileService;
Expand Down Expand Up @@ -130,10 +114,6 @@ export class ShareMenuManager {
sharingData,
shareableUrl,
shareableUrlLocatorParams,
delegatedShareUrlHandler,
embedUrlParamExtensions,
showPublicUrlSwitch,
snapshotShareWarning,
disabledShareUrl,
isDirty,
shareMenuItems: menuItems,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import type { PublicMethodsOf } from '@kbn/utility-types';
import {
ShareMenuRegistry,
ShareRegistry,
ShareMenuRegistrySetup,
ShareMenuRegistryStart,
} from './share_menu_registry';
Expand All @@ -29,7 +29,7 @@ const createStartMock = (): jest.Mocked<ShareMenuRegistryStart> => {
return start;
};

const createMock = (): jest.Mocked<PublicMethodsOf<ShareMenuRegistry>> => {
const createMock = (): jest.Mocked<PublicMethodsOf<ShareRegistry>> => {
const service = {
setup: jest.fn(),
start: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { ShareMenuRegistry } from './share_menu_registry';
import { ShareRegistry } from './share_menu_registry';
import { ShareMenuItemV2, ShareContext } from '../types';

describe('ShareActionsRegistry', () => {
describe('setup', () => {
test('throws when registering duplicate id', () => {
const setup = new ShareMenuRegistry().setup();
const setup = new ShareRegistry().setup();
setup.register({
id: 'csvReports',
getShareMenuItems: () => [],
Expand All @@ -32,7 +32,7 @@ describe('ShareActionsRegistry', () => {
describe('start', () => {
describe('getActions', () => {
test('returns a flat list of actions returned by all providers', () => {
const service = new ShareMenuRegistry();
const service = new ShareRegistry();
const registerFunction = service.setup().register;
const shareAction1 = {} as ShareMenuItemV2;
const shareAction2 = {} as ShareMenuItemV2;
Expand Down
Loading

0 comments on commit c6a9183

Please sign in to comment.