Skip to content

Commit

Permalink
[7.x] [uiActionsEnhanced] reduce bundle size (#112956) (#113114)
Browse files Browse the repository at this point in the history
* [uiActionsEnhanced] reduce bundle size (#112956)

# Conflicts:
#	packages/kbn-optimizer/limits.yml

* adjust bundle limit
  • Loading branch information
Dosant authored Sep 27, 2021
1 parent ac14197 commit 281727d
Show file tree
Hide file tree
Showing 13 changed files with 329 additions and 255 deletions.
6 changes: 3 additions & 3 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ pageLoadAssetSize:
tileMap: 65337
transform: 41151
triggersActionsUi: 100000
uiActions: 95074
uiActionsEnhanced: 313011
upgradeAssistant: 80966
uiActions: 97717
uiActionsEnhanced: 48000
upgradeAssistant: 81241
uptime: 40825
urlDrilldown: 70674
urlForwarding: 32579
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class UrlDrilldown implements Drilldown<Config, ActionContext, ActionFact

public readonly isCompatible = async (config: Config, context: ActionContext) => {
const scope = this.getRuntimeVariables(context);
const { isValid, error } = urlDrilldownValidateUrlTemplate(config.url, scope);
const { isValid, error } = await urlDrilldownValidateUrlTemplate(config.url, scope);

if (!isValid) {
// eslint-disable-next-line no-console
Expand All @@ -139,7 +139,7 @@ export class UrlDrilldown implements Drilldown<Config, ActionContext, ActionFact
return false;
}

const url = this.buildUrl(config, context);
const url = await this.buildUrl(config, context);
const validUrl = this.deps.externalUrl.validateUrl(url);
if (!validUrl) {
return false;
Expand All @@ -148,9 +148,9 @@ export class UrlDrilldown implements Drilldown<Config, ActionContext, ActionFact
return true;
};

private buildUrl(config: Config, context: ActionContext): string {
private async buildUrl(config: Config, context: ActionContext): Promise<string> {
const doEncode = config.encodeUrl ?? true;
const url = urlDrilldownCompileUrl(
const url = await urlDrilldownCompileUrl(
config.url.template,
this.getRuntimeVariables(context),
doEncode
Expand All @@ -159,7 +159,7 @@ export class UrlDrilldown implements Drilldown<Config, ActionContext, ActionFact
}

public readonly getHref = async (config: Config, context: ActionContext): Promise<string> => {
const url = this.buildUrl(config, context);
const url = await this.buildUrl(config, context);
const validUrl = this.deps.externalUrl.validateUrl(url);
if (!validUrl) {
throw new Error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
} from 'src/plugins/embeddable/public';
import { Action, IncompatibleActionError } from '../../../../src/plugins/ui_actions/public';
import { TimeRange } from '../../../../src/plugins/data/public';
import { CustomizeTimeRangeModal } from './customize_time_range_modal';
import { OpenModal, CommonlyUsedRange } from './types';

export const CUSTOM_TIME_RANGE = 'CUSTOM_TIME_RANGE';
Expand Down Expand Up @@ -97,6 +96,9 @@ export class CustomTimeRangeAction implements Action<TimeRangeActionContext> {

// Only here for typescript
if (hasTimeRange(embeddable)) {
const CustomizeTimeRangeModal = await import('./customize_time_range_modal').then(
(m) => m.CustomizeTimeRangeModal
);
const modalSession = this.openModal(
<CustomizeTimeRangeModal
onClose={() => modalSession.close()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { prettyDuration, commonDurationRanges } from '@elastic/eui';
import { IEmbeddable, Embeddable, EmbeddableInput } from 'src/plugins/embeddable/public';
import { Action, IncompatibleActionError } from '../../../../src/plugins/ui_actions/public';
import { TimeRange } from '../../../../src/plugins/data/public';
import { CustomizeTimeRangeModal } from './customize_time_range_modal';
import { doesInheritTimeRange } from './does_inherit_time_range';
import { OpenModal, CommonlyUsedRange } from './types';

Expand Down Expand Up @@ -77,6 +76,9 @@ export class CustomTimeRangeBadge implements Action<TimeBadgeActionContext> {

// Only here for typescript
if (hasTimeRange(embeddable)) {
const CustomizeTimeRangeModal = await import('./customize_time_range_modal').then(
(m) => m.CustomizeTimeRangeModal
);
const modalSession = this.openModal(
<CustomizeTimeRangeModal
onClose={() => modalSession.close()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@

import * as React from 'react';
import { DrilldownManagerDependencies, PublicDrilldownManagerProps } from '../../types';
import { DrilldownManagerProvider } from '../context';
import { DrilldownManager } from './drilldown_manager';

export type PublicDrilldownManagerComponent = React.FC<PublicDrilldownManagerProps>;

const LazyDrilldownManager = React.lazy(() =>
import('./drilldown_manager_with_provider').then((m) => ({
default: m.DrilldownManagerWithProvider,
}))
);

/**
* This HOC creates a "public" `<DrilldownManager>` component `PublicDrilldownManagerComponent`,
* which can be exported from plugin contract for other plugins to consume.
Expand All @@ -21,9 +25,9 @@ export const createPublicDrilldownManager = (
): PublicDrilldownManagerComponent => {
const PublicDrilldownManager: PublicDrilldownManagerComponent = (drilldownManagerProps) => {
return (
<DrilldownManagerProvider {...dependencies} {...drilldownManagerProps}>
<DrilldownManager />
</DrilldownManagerProvider>
<React.Suspense fallback={null}>
<LazyDrilldownManager {...dependencies} {...drilldownManagerProps} />
</React.Suspense>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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 React from 'react';
import { DrilldownManagerProvider, DrilldownManagerProviderProps } from '../context';
import { DrilldownManager } from './drilldown_manager';

export const DrilldownManagerWithProvider: React.FC<DrilldownManagerProviderProps> = (props) => {
return (
<DrilldownManagerProvider {...props}>
<DrilldownManager />
</DrilldownManagerProvider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@
* 2.0.
*/

export * from './drilldown_manager';
export * from './create_public_drilldown_manager';
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* 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 { create as createHandlebars, HelperDelegate, HelperOptions } from 'handlebars';
import { encode, RisonValue } from 'rison-node';
import dateMath from '@elastic/datemath';
import moment, { Moment } from 'moment';
import numeral from '@elastic/numeral';
import { url } from '../../../../../../src/plugins/kibana_utils/public';

const handlebars = createHandlebars();

function createSerializationHelper(
fnName: string,
serializeFn: (value: unknown) => string
): HelperDelegate {
return (...args) => {
const { hash } = args.slice(-1)[0] as HelperOptions;
const hasHash = Object.keys(hash).length > 0;
const hasValues = args.length > 1;
if (hasHash && hasValues) {
throw new Error(`[${fnName}]: both value list and hash are not supported`);
}
if (hasHash) {
if (Object.values(hash).some((v) => typeof v === 'undefined'))
throw new Error(`[${fnName}]: unknown variable`);
return serializeFn(hash);
} else {
const values = args.slice(0, -1) as unknown[];
if (values.some((value) => typeof value === 'undefined'))
throw new Error(`[${fnName}]: unknown variable`);
if (values.length === 0) throw new Error(`[${fnName}]: unknown variable`);
if (values.length === 1) return serializeFn(values[0]);
return serializeFn(values);
}
};
}

handlebars.registerHelper('json', createSerializationHelper('json', JSON.stringify));
handlebars.registerHelper(
'rison',
createSerializationHelper('rison', (v) => encode(v as RisonValue))
);

handlebars.registerHelper('date', (...args) => {
const values = args.slice(0, -1) as [string | Date, string | undefined];
// eslint-disable-next-line prefer-const
let [date, format] = values;
if (typeof date === 'undefined') throw new Error(`[date]: unknown variable`);
let momentDate: Moment | undefined;
if (typeof date === 'string') {
momentDate = dateMath.parse(date);
if (!momentDate || !momentDate.isValid()) {
const ts = Number(date);
if (!Number.isNaN(ts)) {
momentDate = moment(ts);
}
}
} else {
momentDate = moment(date);
}

if (!momentDate || !momentDate.isValid()) {
// do not throw error here, because it could be that in preview `__testValue__` is not parsable,
// but in runtime it is
return date;
}
return format ? momentDate.format(format) : momentDate.toISOString();
});

handlebars.registerHelper('formatNumber', (rawValue: unknown, pattern: string) => {
if (!pattern || typeof pattern !== 'string')
throw new Error(`[formatNumber]: pattern string is required`);
const value = Number(rawValue);
if (rawValue == null || Number.isNaN(value)) return rawValue;
return numeral(value).format(pattern);
});

handlebars.registerHelper('lowercase', (rawValue: unknown) => String(rawValue).toLowerCase());
handlebars.registerHelper('uppercase', (rawValue: unknown) => String(rawValue).toUpperCase());
handlebars.registerHelper('trim', (rawValue: unknown) => String(rawValue).trim());
handlebars.registerHelper('trimLeft', (rawValue: unknown) => String(rawValue).trimLeft());
handlebars.registerHelper('trimRight', (rawValue: unknown) => String(rawValue).trimRight());
handlebars.registerHelper('left', (rawValue: unknown, numberOfChars: number) => {
if (typeof numberOfChars !== 'number')
throw new Error('[left]: expected "number of characters to extract" to be a number');
return String(rawValue).slice(0, numberOfChars);
});
handlebars.registerHelper('right', (rawValue: unknown, numberOfChars: number) => {
if (typeof numberOfChars !== 'number')
throw new Error('[left]: expected "number of characters to extract" to be a number');
return String(rawValue).slice(-numberOfChars);
});
handlebars.registerHelper('mid', (rawValue: unknown, start: number, length: number) => {
if (typeof start !== 'number') throw new Error('[left]: expected "start" to be a number');
if (typeof length !== 'number') throw new Error('[left]: expected "length" to be a number');
return String(rawValue).substr(start, length);
});
handlebars.registerHelper('concat', (...args) => {
const values = args.slice(0, -1) as unknown[];
return values.join('');
});
handlebars.registerHelper('split', (...args) => {
const [str, splitter] = args.slice(0, -1) as [string, string];
if (typeof splitter !== 'string') throw new Error('[split] "splitter" expected to be a string');
return String(str).split(splitter);
});
handlebars.registerHelper('replace', (...args) => {
const [str, searchString, valueString] = args.slice(0, -1) as [string, string, string];
if (typeof searchString !== 'string' || typeof valueString !== 'string')
throw new Error(
'[replace]: "searchString" and "valueString" parameters expected to be strings, but not a string or missing'
);
return String(str).split(searchString).join(valueString);
});

handlebars.registerHelper('encodeURIComponent', (component: unknown) => {
const str = String(component);
return encodeURIComponent(str);
});
handlebars.registerHelper('encodeURIQuery', (component: unknown) => {
const str = String(component);
return url.encodeUriQuery(str);
});

export { handlebars };
Loading

0 comments on commit 281727d

Please sign in to comment.