diff --git a/x-pack/plugins/canvas/.storybook/config.js b/x-pack/plugins/canvas/.storybook/config.js
index c808a672711aba..04b4e2a8e7b4b0 100644
--- a/x-pack/plugins/canvas/.storybook/config.js
+++ b/x-pack/plugins/canvas/.storybook/config.js
@@ -59,6 +59,9 @@ function loadStories() {
// Find all files ending in *.examples.ts
const req = require.context('./..', true, /.(stories|examples).tsx$/);
req.keys().forEach(filename => req(filename));
+
+ // Import Canvas CSS
+ require('../public/style/index.scss')
}
// Set up the Storybook environment with custom settings.
diff --git a/x-pack/plugins/canvas/.storybook/webpack.config.js b/x-pack/plugins/canvas/.storybook/webpack.config.js
index 4d83a3d4fa70f9..45a5303d8b0db1 100644
--- a/x-pack/plugins/canvas/.storybook/webpack.config.js
+++ b/x-pack/plugins/canvas/.storybook/webpack.config.js
@@ -199,6 +199,7 @@ module.exports = async ({ config }) => {
config.resolve.alias['ui/url/absolute_to_parsed_url'] = path.resolve(__dirname, '../tasks/mocks/uiAbsoluteToParsedUrl');
config.resolve.alias['ui/chrome'] = path.resolve(__dirname, '../tasks/mocks/uiChrome');
config.resolve.alias.ui = path.resolve(KIBANA_ROOT, 'src/legacy/ui/public');
+ config.resolve.alias['src/legacy/ui/public/styles/styling_constants'] = path.resolve(KIBANA_ROOT, 'src/legacy/ui/public/styles/_styling_constants.scss');
config.resolve.alias.ng_mock$ = path.resolve(KIBANA_ROOT, 'src/test_utils/public/ng_mock');
return config;
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/palette.test.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/palette.test.js
index af03297ad666ba..01cabd171c2fed 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/palette.test.js
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/palette.test.js
@@ -5,7 +5,7 @@
*/
import { functionWrapper } from '../../../__tests__/helpers/function_wrapper';
-import { palettes } from '../../../common/lib/palettes';
+import { paulTor14 } from '../../../common/lib/palettes';
import { palette } from './palette';
describe('palette', () => {
@@ -25,7 +25,7 @@ describe('palette', () => {
it('defaults to pault_tor_14 colors', () => {
const result = fn(null);
- expect(result.colors).toEqual(palettes.paul_tor_14.colors);
+ expect(result.colors).toEqual(paulTor14.colors);
});
});
@@ -47,17 +47,17 @@ describe('palette', () => {
describe('reverse', () => {
it('reverses order of the colors', () => {
const result = fn(null, { reverse: true });
- expect(result.colors).toEqual(palettes.paul_tor_14.colors.reverse());
+ expect(result.colors).toEqual(paulTor14.colors.reverse());
});
it('keeps the original order of the colors', () => {
const result = fn(null, { reverse: false });
- expect(result.colors).toEqual(palettes.paul_tor_14.colors);
+ expect(result.colors).toEqual(paulTor14.colors);
});
it(`defaults to 'false`, () => {
const result = fn(null);
- expect(result.colors).toEqual(palettes.paul_tor_14.colors);
+ expect(result.colors).toEqual(paulTor14.colors);
});
});
});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/palette.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/palette.ts
index f27abe261e2e20..50d62a19b23612 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/palette.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/palette.ts
@@ -5,8 +5,7 @@
*/
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
-// @ts-expect-error untyped local
-import { palettes } from '../../../common/lib/palettes';
+import { paulTor14 } from '../../../common/lib/palettes';
import { getFunctionHelp } from '../../../i18n';
interface Arguments {
@@ -52,7 +51,7 @@ export function palette(): ExpressionFunctionDefinition<'palette', null, Argumen
},
fn: (input, args) => {
const { color, reverse, gradient } = args;
- const colors = ([] as string[]).concat(color || palettes.paul_tor_14.colors);
+ const colors = ([] as string[]).concat(color || paulTor14.colors);
return {
type: 'palette',
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/__examples__/__snapshots__/palette.stories.storyshot b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/__examples__/__snapshots__/palette.stories.storyshot
new file mode 100644
index 00000000000000..385b16d3d8e8e1
--- /dev/null
+++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/__examples__/__snapshots__/palette.stories.storyshot
@@ -0,0 +1,86 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Storyshots arguments/Palette default 1`] = `
+
+
+
+
+
+
+
+ Select an option:
+
+ , is selected
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/__examples__/palette.stories.tsx b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/__examples__/palette.stories.tsx
new file mode 100644
index 00000000000000..6bc285a3d66d29
--- /dev/null
+++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/__examples__/palette.stories.tsx
@@ -0,0 +1,32 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+import { storiesOf } from '@storybook/react';
+import React from 'react';
+import { action } from '@storybook/addon-actions';
+import { PaletteArgInput } from '../palette';
+import { paulTor14 } from '../../../../common/lib/palettes';
+
+storiesOf('arguments/Palette', module).add('default', () => (
+
+));
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/index.ts
index 94a9cf28aef69d..ddf428d884917c 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/index.ts
@@ -15,7 +15,6 @@ import { imageUpload } from './image_upload';
// @ts-expect-error untyped local
import { number } from './number';
import { numberFormatInitializer } from './number_format';
-// @ts-expect-error untyped local
import { palette } from './palette';
// @ts-expect-error untyped local
import { percentage } from './percentage';
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.js b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.tsx
similarity index 58%
rename from x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.js
rename to x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.tsx
index eddaa20a4800ee..a33d000a1f6563 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.js
+++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.tsx
@@ -4,45 +4,63 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
+import React, { FC } from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';
import { getType } from '@kbn/interpreter/common';
+import { ExpressionAstFunction, ExpressionAstExpression } from 'src/plugins/expressions';
import { PalettePicker } from '../../../public/components/palette_picker';
import { templateFromReactComponent } from '../../../public/lib/template_from_react_component';
import { ArgumentStrings } from '../../../i18n';
+import { identifyPalette, ColorPalette } from '../../../common/lib';
const { Palette: strings } = ArgumentStrings;
-const PaletteArgInput = ({ onValueChange, argValue, renderError }) => {
- // Why is this neccesary? Does the dialog really need to know what parameter it is setting?
-
- const throwNotParsed = () => renderError();
+interface Props {
+ onValueChange: (value: ExpressionAstExpression) => void;
+ argValue: ExpressionAstExpression;
+ renderError: () => void;
+ argId?: string;
+}
+export const PaletteArgInput: FC = ({ onValueChange, argId, argValue, renderError }) => {
// TODO: This is weird, its basically a reimplementation of what the interpretter would return.
- // Probably a better way todo this, and maybe a better way to handle template stype objects in general?
- function astToPalette({ chain }) {
+ // Probably a better way todo this, and maybe a better way to handle template type objects in general?
+ const astToPalette = ({ chain }: { chain: ExpressionAstFunction[] }): ColorPalette | null => {
if (chain.length !== 1 || chain[0].function !== 'palette') {
- throwNotParsed();
+ renderError();
+ return null;
}
+
try {
const colors = chain[0].arguments._.map((astObj) => {
if (getType(astObj) !== 'string') {
- throwNotParsed();
+ renderError();
}
return astObj;
- });
+ }) as string[];
- const gradient = get(chain[0].arguments.gradient, '[0]');
+ const gradient = get(chain[0].arguments.gradient, '[0]');
+ const palette = identifyPalette({ colors, gradient });
- return { colors, gradient };
+ if (palette) {
+ return palette;
+ }
+
+ return ({
+ id: 'custom',
+ label: strings.getCustomPaletteLabel(),
+ colors,
+ gradient,
+ } as any) as ColorPalette;
} catch (e) {
- throwNotParsed();
+ renderError();
}
- }
+ return null;
+ };
- function handleChange(palette) {
- const astObj = {
+ const handleChange = (palette: ColorPalette): void => {
+ const astObj: ExpressionAstExpression = {
type: 'expression',
chain: [
{
@@ -57,16 +75,20 @@ const PaletteArgInput = ({ onValueChange, argValue, renderError }) => {
};
onValueChange(astObj);
- }
+ };
const palette = astToPalette(argValue);
- return (
-
- );
+ if (!palette) {
+ renderError();
+ return null;
+ }
+
+ return ;
};
PaletteArgInput.propTypes = {
+ argId: PropTypes.string,
onValueChange: PropTypes.func.isRequired,
argValue: PropTypes.any.isRequired,
renderError: PropTypes.func,
diff --git a/x-pack/plugins/canvas/common/lib/index.ts b/x-pack/plugins/canvas/common/lib/index.ts
index 4cb3cbbb9b4e6d..6bd7e0bc9948fd 100644
--- a/x-pack/plugins/canvas/common/lib/index.ts
+++ b/x-pack/plugins/canvas/common/lib/index.ts
@@ -26,7 +26,6 @@ export * from './hex_to_rgb';
export * from './httpurl';
// @ts-expect-error missing local definition
export * from './missing_asset';
-// @ts-expect-error missing local definition
export * from './palettes';
export * from './pivot_object_array';
// @ts-expect-error missing local definition
diff --git a/x-pack/plugins/canvas/common/lib/palettes.js b/x-pack/plugins/canvas/common/lib/palettes.js
deleted file mode 100644
index 3fe977ec3862c4..00000000000000
--- a/x-pack/plugins/canvas/common/lib/palettes.js
+++ /dev/null
@@ -1,152 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-/*
- This should be pluggable
-*/
-
-export const palettes = {
- paul_tor_14: {
- colors: [
- '#882E72',
- '#B178A6',
- '#D6C1DE',
- '#1965B0',
- '#5289C7',
- '#7BAFDE',
- '#4EB265',
- '#90C987',
- '#CAE0AB',
- '#F7EE55',
- '#F6C141',
- '#F1932D',
- '#E8601C',
- '#DC050C',
- ],
- gradient: false,
- },
- paul_tor_21: {
- colors: [
- '#771155',
- '#AA4488',
- '#CC99BB',
- '#114477',
- '#4477AA',
- '#77AADD',
- '#117777',
- '#44AAAA',
- '#77CCCC',
- '#117744',
- '#44AA77',
- '#88CCAA',
- '#777711',
- '#AAAA44',
- '#DDDD77',
- '#774411',
- '#AA7744',
- '#DDAA77',
- '#771122',
- '#AA4455',
- '#DD7788',
- ],
- gradient: false,
- },
- earth_tones: {
- colors: [
- '#842113',
- '#984d23',
- '#32221c',
- '#739379',
- '#dab150',
- '#4d2521',
- '#716c49',
- '#bb3918',
- '#7e5436',
- '#c27c34',
- '#72392e',
- '#8f8b7e',
- ],
- gradient: false,
- },
- canvas: {
- colors: [
- '#01A4A4',
- '#CC6666',
- '#D0D102',
- '#616161',
- '#00A1CB',
- '#32742C',
- '#F18D05',
- '#113F8C',
- '#61AE24',
- '#D70060',
- ],
- gradient: false,
- },
- color_blind: {
- colors: [
- '#1ea593',
- '#2b70f7',
- '#ce0060',
- '#38007e',
- '#fca5d3',
- '#f37020',
- '#e49e29',
- '#b0916f',
- '#7b000b',
- '#34130c',
- ],
- gradient: false,
- },
- elastic_teal: {
- colors: ['#C5FAF4', '#0F6259'],
- gradient: true,
- },
- elastic_blue: {
- colors: ['#7ECAE3', '#003A4D'],
- gradient: true,
- },
- elastic_yellow: {
- colors: ['#FFE674', '#4D3F00'],
- gradient: true,
- },
- elastic_pink: {
- colors: ['#FEA8D5', '#531E3A'],
- gradient: true,
- },
- elastic_green: {
- colors: ['#D3FB71', '#131A00'],
- gradient: true,
- },
- elastic_orange: {
- colors: ['#FFC68A', '#7B3F00'],
- gradient: true,
- },
- elastic_purple: {
- colors: ['#CCC7DF', '#130351'],
- gradient: true,
- },
- green_blue_red: {
- colors: ['#D3FB71', '#7ECAE3', '#f03b20'],
- gradient: true,
- },
- yellow_green: {
- colors: ['#f7fcb9', '#addd8e', '#31a354'],
- gradient: true,
- },
- yellow_blue: {
- colors: ['#edf8b1', '#7fcdbb', '#2c7fb8'],
- gradient: true,
- },
- yellow_red: {
- colors: ['#ffeda0', '#feb24c', '#f03b20'],
- gradient: true,
- },
- instagram: {
- colors: ['#833ab4', '#fd1d1d', '#fcb045'],
- gradient: true,
- },
-};
diff --git a/x-pack/plugins/canvas/common/lib/palettes.ts b/x-pack/plugins/canvas/common/lib/palettes.ts
new file mode 100644
index 00000000000000..1469ba63967c0e
--- /dev/null
+++ b/x-pack/plugins/canvas/common/lib/palettes.ts
@@ -0,0 +1,263 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { isEqual } from 'lodash';
+import { LibStrings } from '../../i18n';
+
+const { Palettes: strings } = LibStrings;
+
+/**
+ * This type contains a unions of all supported palette ids.
+ */
+export type PaletteID = typeof palettes[number]['id'];
+
+/**
+ * An interface representing a color palette in Canvas, with a textual label and a set of
+ * hex values.
+ */
+export interface ColorPalette {
+ id: PaletteID;
+ label: string;
+ colors: string[];
+ gradient: boolean;
+}
+
+// This function allows one to create a strongly-typed palette for inclusion in
+// the palette collection. As a result, the values and labels are known to the
+// type system, preventing one from specifying a non-existent palette at build
+// time.
+function createPalette<
+ RawPalette extends {
+ id: RawPaletteID;
+ },
+ RawPaletteID extends string
+>(palette: RawPalette) {
+ return palette;
+}
+
+/**
+ * Return a palette given a set of colors and gradient. Returns undefined if the
+ * palette doesn't match.
+ */
+export const identifyPalette = (
+ input: Pick
+): ColorPalette | undefined => {
+ return palettes.find((palette) => {
+ const { colors, gradient } = palette;
+ return gradient === input.gradient && isEqual(colors, input.colors);
+ });
+};
+
+export const paulTor14 = createPalette({
+ id: 'paul_tor_14',
+ label: 'Paul Tor 14',
+ colors: [
+ '#882E72',
+ '#B178A6',
+ '#D6C1DE',
+ '#1965B0',
+ '#5289C7',
+ '#7BAFDE',
+ '#4EB265',
+ '#90C987',
+ '#CAE0AB',
+ '#F7EE55',
+ '#F6C141',
+ '#F1932D',
+ '#E8601C',
+ '#DC050C',
+ ],
+ gradient: false,
+});
+
+export const paulTor21 = createPalette({
+ id: 'paul_tor_21',
+ label: 'Paul Tor 21',
+ colors: [
+ '#771155',
+ '#AA4488',
+ '#CC99BB',
+ '#114477',
+ '#4477AA',
+ '#77AADD',
+ '#117777',
+ '#44AAAA',
+ '#77CCCC',
+ '#117744',
+ '#44AA77',
+ '#88CCAA',
+ '#777711',
+ '#AAAA44',
+ '#DDDD77',
+ '#774411',
+ '#AA7744',
+ '#DDAA77',
+ '#771122',
+ '#AA4455',
+ '#DD7788',
+ ],
+ gradient: false,
+});
+
+export const earthTones = createPalette({
+ id: 'earth_tones',
+ label: strings.getEarthTones(),
+ colors: [
+ '#842113',
+ '#984d23',
+ '#32221c',
+ '#739379',
+ '#dab150',
+ '#4d2521',
+ '#716c49',
+ '#bb3918',
+ '#7e5436',
+ '#c27c34',
+ '#72392e',
+ '#8f8b7e',
+ ],
+ gradient: false,
+});
+
+export const canvas = createPalette({
+ id: 'canvas',
+ label: strings.getCanvas(),
+ colors: [
+ '#01A4A4',
+ '#CC6666',
+ '#D0D102',
+ '#616161',
+ '#00A1CB',
+ '#32742C',
+ '#F18D05',
+ '#113F8C',
+ '#61AE24',
+ '#D70060',
+ ],
+ gradient: false,
+});
+
+export const colorBlind = createPalette({
+ id: 'color_blind',
+ label: strings.getColorBlind(),
+ colors: [
+ '#1ea593',
+ '#2b70f7',
+ '#ce0060',
+ '#38007e',
+ '#fca5d3',
+ '#f37020',
+ '#e49e29',
+ '#b0916f',
+ '#7b000b',
+ '#34130c',
+ ],
+ gradient: false,
+});
+
+export const elasticTeal = createPalette({
+ id: 'elastic_teal',
+ label: strings.getElasticTeal(),
+ colors: ['#7ECAE3', '#003A4D'],
+ gradient: true,
+});
+
+export const elasticBlue = createPalette({
+ id: 'elastic_blue',
+ label: strings.getElasticBlue(),
+ colors: ['#C5FAF4', '#0F6259'],
+ gradient: true,
+});
+
+export const elasticYellow = createPalette({
+ id: 'elastic_yellow',
+ label: strings.getElasticYellow(),
+ colors: ['#FFE674', '#4D3F00'],
+ gradient: true,
+});
+
+export const elasticPink = createPalette({
+ id: 'elastic_pink',
+ label: strings.getElasticPink(),
+ colors: ['#FEA8D5', '#531E3A'],
+ gradient: true,
+});
+
+export const elasticGreen = createPalette({
+ id: 'elastic_green',
+ label: strings.getElasticGreen(),
+ colors: ['#D3FB71', '#131A00'],
+ gradient: true,
+});
+
+export const elasticOrange = createPalette({
+ id: 'elastic_orange',
+ label: strings.getElasticOrange(),
+ colors: ['#FFC68A', '#7B3F00'],
+ gradient: true,
+});
+
+export const elasticPurple = createPalette({
+ id: 'elastic_purple',
+ label: strings.getElasticPurple(),
+ colors: ['#CCC7DF', '#130351'],
+ gradient: true,
+});
+
+export const greenBlueRed = createPalette({
+ id: 'green_blue_red',
+ label: strings.getGreenBlueRed(),
+ colors: ['#D3FB71', '#7ECAE3', '#f03b20'],
+ gradient: true,
+});
+
+export const yellowGreen = createPalette({
+ id: 'yellow_green',
+ label: strings.getYellowGreen(),
+ colors: ['#f7fcb9', '#addd8e', '#31a354'],
+ gradient: true,
+});
+
+export const yellowBlue = createPalette({
+ id: 'yellow_blue',
+ label: strings.getYellowBlue(),
+ colors: ['#edf8b1', '#7fcdbb', '#2c7fb8'],
+ gradient: true,
+});
+
+export const yellowRed = createPalette({
+ id: 'yellow_red',
+ label: strings.getYellowRed(),
+ colors: ['#ffeda0', '#feb24c', '#f03b20'],
+ gradient: true,
+});
+
+export const instagram = createPalette({
+ id: 'instagram',
+ label: strings.getInstagram(),
+ colors: ['#833ab4', '#fd1d1d', '#fcb045'],
+ gradient: true,
+});
+
+export const palettes = [
+ paulTor14,
+ paulTor21,
+ earthTones,
+ canvas,
+ colorBlind,
+ elasticTeal,
+ elasticBlue,
+ elasticYellow,
+ elasticPink,
+ elasticGreen,
+ elasticOrange,
+ elasticPurple,
+ greenBlueRed,
+ yellowGreen,
+ yellowBlue,
+ yellowRed,
+ instagram,
+];
diff --git a/x-pack/plugins/canvas/i18n/components.ts b/x-pack/plugins/canvas/i18n/components.ts
index de16bc2101e8cf..0b512c80b209ba 100644
--- a/x-pack/plugins/canvas/i18n/components.ts
+++ b/x-pack/plugins/canvas/i18n/components.ts
@@ -586,6 +586,16 @@ export const ComponentStrings = {
defaultMessage: 'Delete',
}),
},
+ PalettePicker: {
+ getEmptyPaletteLabel: () =>
+ i18n.translate('xpack.canvas.palettePicker.emptyPaletteLabel', {
+ defaultMessage: 'None',
+ }),
+ getNoPaletteFoundErrorTitle: () =>
+ i18n.translate('xpack.canvas.palettePicker.noPaletteFoundErrorTitle', {
+ defaultMessage: 'Color palette not found',
+ }),
+ },
SavedElementsModal: {
getAddNewElementDescription: () =>
i18n.translate('xpack.canvas.savedElementsModal.addNewElementDescription', {
diff --git a/x-pack/plugins/canvas/i18n/constants.ts b/x-pack/plugins/canvas/i18n/constants.ts
index 099effc697fc56..af82d0afc7e9ff 100644
--- a/x-pack/plugins/canvas/i18n/constants.ts
+++ b/x-pack/plugins/canvas/i18n/constants.ts
@@ -20,6 +20,7 @@ export const FONT_FAMILY = '`font-family`';
export const FONT_WEIGHT = '`font-weight`';
export const HEX = 'HEX';
export const HTML = 'HTML';
+export const INSTAGRAM = 'Instagram';
export const ISO8601 = 'ISO8601';
export const JS = 'JavaScript';
export const JSON = 'JSON';
diff --git a/x-pack/plugins/canvas/i18n/index.ts b/x-pack/plugins/canvas/i18n/index.ts
index 864311d34aca08..3bf1fa077130cd 100644
--- a/x-pack/plugins/canvas/i18n/index.ts
+++ b/x-pack/plugins/canvas/i18n/index.ts
@@ -11,6 +11,7 @@ export * from './errors';
export * from './expression_types';
export * from './elements';
export * from './functions';
+export * from './lib';
export * from './renderers';
export * from './shortcuts';
export * from './tags';
diff --git a/x-pack/plugins/canvas/i18n/lib.ts b/x-pack/plugins/canvas/i18n/lib.ts
new file mode 100644
index 00000000000000..eca6dc44354a27
--- /dev/null
+++ b/x-pack/plugins/canvas/i18n/lib.ts
@@ -0,0 +1,92 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+import { CANVAS, INSTAGRAM } from './constants';
+
+export const LibStrings = {
+ Palettes: {
+ getEarthTones: () =>
+ i18n.translate('xpack.canvas.lib.palettes.earthTonesLabel', {
+ defaultMessage: 'Earth Tones',
+ }),
+ getCanvas: () =>
+ i18n.translate('xpack.canvas.lib.palettes.canvasLabel', {
+ defaultMessage: '{CANVAS}',
+ values: {
+ CANVAS,
+ },
+ }),
+
+ getColorBlind: () =>
+ i18n.translate('xpack.canvas.lib.palettes.colorBlindLabel', {
+ defaultMessage: 'Color Blind',
+ }),
+
+ getElasticTeal: () =>
+ i18n.translate('xpack.canvas.lib.palettes.elasticTealLabel', {
+ defaultMessage: 'Elastic Teal',
+ }),
+
+ getElasticBlue: () =>
+ i18n.translate('xpack.canvas.lib.palettes.elasticBlueLabel', {
+ defaultMessage: 'Elastic Blue',
+ }),
+
+ getElasticYellow: () =>
+ i18n.translate('xpack.canvas.lib.palettes.elasticYellowLabel', {
+ defaultMessage: 'Elastic Yellow',
+ }),
+
+ getElasticPink: () =>
+ i18n.translate('xpack.canvas.lib.palettes.elasticPinkLabel', {
+ defaultMessage: 'Elastic Pink',
+ }),
+
+ getElasticGreen: () =>
+ i18n.translate('xpack.canvas.lib.palettes.elasticGreenLabel', {
+ defaultMessage: 'Elastic Green',
+ }),
+
+ getElasticOrange: () =>
+ i18n.translate('xpack.canvas.lib.palettes.elasticOrangeLabel', {
+ defaultMessage: 'Elastic Orange',
+ }),
+
+ getElasticPurple: () =>
+ i18n.translate('xpack.canvas.lib.palettes.elasticPurpleLabel', {
+ defaultMessage: 'Elastic Purple',
+ }),
+
+ getGreenBlueRed: () =>
+ i18n.translate('xpack.canvas.lib.palettes.greenBlueRedLabel', {
+ defaultMessage: 'Green, Blue, Red',
+ }),
+
+ getYellowGreen: () =>
+ i18n.translate('xpack.canvas.lib.palettes.yellowGreenLabel', {
+ defaultMessage: 'Yellow, Green',
+ }),
+
+ getYellowBlue: () =>
+ i18n.translate('xpack.canvas.lib.palettes.yellowBlueLabel', {
+ defaultMessage: 'Yellow, Blue',
+ }),
+
+ getYellowRed: () =>
+ i18n.translate('xpack.canvas.lib.palettes.yellowRedLabel', {
+ defaultMessage: 'Yellow, Red',
+ }),
+
+ getInstagram: () =>
+ i18n.translate('xpack.canvas.lib.palettes.instagramLabel', {
+ defaultMessage: '{INSTAGRAM}',
+ values: {
+ INSTAGRAM,
+ },
+ }),
+ },
+};
diff --git a/x-pack/plugins/canvas/i18n/ui.ts b/x-pack/plugins/canvas/i18n/ui.ts
index f69f9e747ab902..bc282db203be2e 100644
--- a/x-pack/plugins/canvas/i18n/ui.ts
+++ b/x-pack/plugins/canvas/i18n/ui.ts
@@ -232,7 +232,11 @@ export const ArgumentStrings = {
}),
getHelp: () =>
i18n.translate('xpack.canvas.uis.arguments.paletteLabel', {
- defaultMessage: 'Choose a color palette',
+ defaultMessage: 'The collection of colors used to render the element',
+ }),
+ getCustomPaletteLabel: () =>
+ i18n.translate('xpack.canvas.uis.arguments.customPaletteLabel', {
+ defaultMessage: 'Custom',
}),
},
Percentage: {
diff --git a/x-pack/plugins/canvas/public/components/palette_picker/__examples__/__snapshots__/palette_picker.stories.storyshot b/x-pack/plugins/canvas/public/components/palette_picker/__examples__/__snapshots__/palette_picker.stories.storyshot
new file mode 100644
index 00000000000000..d3809b4c3979f1
--- /dev/null
+++ b/x-pack/plugins/canvas/public/components/palette_picker/__examples__/__snapshots__/palette_picker.stories.storyshot
@@ -0,0 +1,237 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Storyshots components/Color/PalettePicker clearable 1`] = `
+
+
+
+
+
+
+
+ Select an option: None, is selected
+
+
+ None
+
+
+
+
+
+
+
+`;
+
+exports[`Storyshots components/Color/PalettePicker default 1`] = `
+
+
+
+
+
+
+
+ Select an option:
+
+ , is selected
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Storyshots components/Color/PalettePicker interactive 1`] = `
+
+
+
+
+
+
+
+ Select an option:
+
+ , is selected
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/canvas/public/components/palette_picker/__examples__/palette_picker.stories.tsx b/x-pack/plugins/canvas/public/components/palette_picker/__examples__/palette_picker.stories.tsx
new file mode 100644
index 00000000000000..b1ae860e80efb7
--- /dev/null
+++ b/x-pack/plugins/canvas/public/components/palette_picker/__examples__/palette_picker.stories.tsx
@@ -0,0 +1,25 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React, { FC, useState } from 'react';
+import { action } from '@storybook/addon-actions';
+import { storiesOf } from '@storybook/react';
+import { PalettePicker } from '../palette_picker';
+
+import { paulTor14, ColorPalette } from '../../../../common/lib/palettes';
+
+const Interactive: FC = () => {
+ const [palette, setPalette] = useState(paulTor14);
+ return ;
+};
+
+storiesOf('components/Color/PalettePicker', module)
+ .addDecorator((fn) => {fn()}
)
+ .add('default', () => )
+ .add('clearable', () => (
+
+ ))
+ .add('interactive', () => );
diff --git a/x-pack/plugins/canvas/public/components/palette_swatch/index.js b/x-pack/plugins/canvas/public/components/palette_picker/index.ts
similarity index 62%
rename from x-pack/plugins/canvas/public/components/palette_swatch/index.js
rename to x-pack/plugins/canvas/public/components/palette_picker/index.ts
index 2be37a8338b2b3..840600698c5a42 100644
--- a/x-pack/plugins/canvas/public/components/palette_swatch/index.js
+++ b/x-pack/plugins/canvas/public/components/palette_picker/index.ts
@@ -4,8 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { pure } from 'recompose';
-
-import { PaletteSwatch as Component } from './palette_swatch';
-
-export const PaletteSwatch = pure(Component);
+export { PalettePicker } from './palette_picker';
diff --git a/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.js b/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.js
deleted file mode 100644
index ca2a499feb84cb..00000000000000
--- a/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.js
+++ /dev/null
@@ -1,60 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
-import { map } from 'lodash';
-import { Popover } from '../popover';
-import { PaletteSwatch } from '../palette_swatch';
-import { palettes } from '../../../common/lib/palettes';
-
-export const PalettePicker = ({ onChange, value, anchorPosition, ariaLabel }) => {
- const button = (handleClick) => (
-
-
-
- );
-
- return (
-
- {() => (
-
- {map(palettes, (palette, name) => (
-
onChange(palette)}
- className="canvasPalettePicker__swatch"
- style={{ width: '100%' }}
- >
-
-
- {name.replace(/_/g, ' ')}
-
-
-
-
-
-
- ))}
-
- )}
-
- );
-};
-
-PalettePicker.propTypes = {
- value: PropTypes.object,
- onChange: PropTypes.func,
- anchorPosition: PropTypes.string,
-};
diff --git a/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.scss b/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.scss
deleted file mode 100644
index f837d47682f61f..00000000000000
--- a/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.scss
+++ /dev/null
@@ -1,42 +0,0 @@
-.canvasPalettePicker {
- display: inline-block;
- width: 100%;
-}
-
-.canvasPalettePicker__swatches {
- @include euiScrollBar;
-
- width: 280px;
- height: 250px;
- overflow-y: scroll;
-}
-
-.canvasPalettePicker__swatchesPanel {
- padding: $euiSizeS 0 !important; // sass-lint:disable-line no-important
-}
-
-.canvasPalettePicker__swatch {
- padding: $euiSizeS $euiSize;
-
- &:hover,
- &:focus {
- text-decoration: underline;
- background-color: $euiColorLightestShade;
-
- .canvasPaletteSwatch,
- .canvasPaletteSwatch__background {
- transform: scaleY(2);
- }
-
- .canvasPalettePicker__label {
- color: $euiTextColor;
- }
- }
-}
-
-.canvasPalettePicker__label {
- font-size: $euiFontSizeXS;
- text-transform: capitalize;
- text-align: left;
- color: $euiColorDarkShade;
-}
diff --git a/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.tsx b/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.tsx
new file mode 100644
index 00000000000000..dec09a5335d950
--- /dev/null
+++ b/x-pack/plugins/canvas/public/components/palette_picker/palette_picker.tsx
@@ -0,0 +1,92 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React, { FC } from 'react';
+import PropTypes from 'prop-types';
+import { EuiColorPalettePicker, EuiColorPalettePickerPaletteProps } from '@elastic/eui';
+import { palettes, ColorPalette } from '../../../common/lib/palettes';
+import { ComponentStrings } from '../../../i18n';
+
+const { PalettePicker: strings } = ComponentStrings;
+
+interface RequiredProps {
+ id?: string;
+ onChange?: (palette: ColorPalette) => void;
+ palette: ColorPalette;
+ clearable?: false;
+}
+
+interface ClearableProps {
+ id?: string;
+ onChange?: (palette: ColorPalette | null) => void;
+ palette: ColorPalette | null;
+ clearable: true;
+}
+
+type Props = RequiredProps | ClearableProps;
+
+export const PalettePicker: FC = (props) => {
+ const colorPalettes: EuiColorPalettePickerPaletteProps[] = palettes.map((item) => ({
+ value: item.id,
+ title: item.label,
+ type: item.gradient ? 'gradient' : 'fixed',
+ palette: item.colors,
+ }));
+
+ if (props.clearable) {
+ const { palette, onChange = () => {} } = props;
+
+ colorPalettes.unshift({
+ value: 'clear',
+ title: strings.getEmptyPaletteLabel(),
+ type: 'text',
+ });
+
+ const onPickerChange = (value: string) => {
+ const canvasPalette = palettes.find((item) => item.id === value);
+ onChange(canvasPalette || null);
+ };
+
+ return (
+
+ );
+ }
+
+ const { palette, onChange = () => {} } = props;
+
+ const onPickerChange = (value: string) => {
+ const canvasPalette = palettes.find((item) => item.id === value);
+
+ if (!canvasPalette) {
+ throw new Error(strings.getNoPaletteFoundErrorTitle());
+ }
+
+ onChange(canvasPalette);
+ };
+
+ return (
+
+ );
+};
+
+PalettePicker.propTypes = {
+ id: PropTypes.string,
+ palette: PropTypes.object,
+ onChange: PropTypes.func,
+ clearable: PropTypes.bool,
+};
diff --git a/x-pack/plugins/canvas/public/components/palette_swatch/palette_swatch.js b/x-pack/plugins/canvas/public/components/palette_swatch/palette_swatch.js
deleted file mode 100644
index 71d16260e00c73..00000000000000
--- a/x-pack/plugins/canvas/public/components/palette_swatch/palette_swatch.js
+++ /dev/null
@@ -1,46 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React from 'react';
-import PropTypes from 'prop-types';
-
-export const PaletteSwatch = ({ colors, gradient }) => {
- let colorBoxes;
-
- if (!gradient) {
- colorBoxes = colors.map((color) => (
-
- ));
- } else {
- colorBoxes = [
-
,
- ];
- }
-
- return (
-
- );
-};
-
-PaletteSwatch.propTypes = {
- colors: PropTypes.array,
- gradient: PropTypes.bool,
-};
diff --git a/x-pack/plugins/canvas/public/components/palette_swatch/palette_swatch.scss b/x-pack/plugins/canvas/public/components/palette_swatch/palette_swatch.scss
deleted file mode 100644
index b57c520a5b07f2..00000000000000
--- a/x-pack/plugins/canvas/public/components/palette_swatch/palette_swatch.scss
+++ /dev/null
@@ -1,35 +0,0 @@
-.canvasPaletteSwatch {
- display: inline-block;
- position: relative;
- height: $euiSizeXS;
- width: 100%;
- overflow: hidden;
- text-align: left;
- transform: scaleY(1);
- transition: transform $euiAnimSlightResistance $euiAnimSpeedExtraFast;
-
- .canvasPaletteSwatch__background {
- position: absolute;
- height: $euiSizeXS;
- top: 0;
- left: 0;
- width: 100%;
- transform: scaleY(1);
- transition: transform $euiAnimSlightResistance $euiAnimSpeedExtraFast;
- }
-
- .canvasPaletteSwatch__foreground {
- position: absolute;
- height: 100%; // TODO: No idea why this can't be 25, but it leaves a 1px white spot in the palettePicker if its 25
- top: 0;
- left: 0;
- white-space: nowrap;
- width: 100%;
- display: flex;
- }
-
- .canvasPaletteSwatch__box {
- display: inline-block;
- width: 100%;
- }
-}
diff --git a/x-pack/plugins/canvas/public/style/index.scss b/x-pack/plugins/canvas/public/style/index.scss
index 7b4e1271cca1df..78a34a58f5f782 100644
--- a/x-pack/plugins/canvas/public/style/index.scss
+++ b/x-pack/plugins/canvas/public/style/index.scss
@@ -39,8 +39,6 @@
@import '../components/loading/loading';
@import '../components/navbar/navbar';
@import '../components/page_manager/page_manager';
-@import '../components/palette_picker/palette_picker';
-@import '../components/palette_swatch/palette_swatch';
@import '../components/positionable/positionable';
@import '../components/rotation_handle/rotation_handle';
@import '../components/shape_preview/shape_preview';
diff --git a/x-pack/plugins/ingest_manager/common/types/rest_spec/index.ts b/x-pack/plugins/ingest_manager/common/types/rest_spec/index.ts
index eb212050ef53ef..294e10aabe4efc 100644
--- a/x-pack/plugins/ingest_manager/common/types/rest_spec/index.ts
+++ b/x-pack/plugins/ingest_manager/common/types/rest_spec/index.ts
@@ -12,6 +12,7 @@ export * from './fleet_setup';
export * from './epm';
export * from './enrollment_api_key';
export * from './install_script';
+export * from './ingest_setup';
export * from './output';
export * from './settings';
export * from './app';
diff --git a/x-pack/plugins/canvas/public/components/palette_picker/index.js b/x-pack/plugins/ingest_manager/common/types/rest_spec/ingest_setup.ts
similarity index 62%
rename from x-pack/plugins/canvas/public/components/palette_picker/index.js
rename to x-pack/plugins/ingest_manager/common/types/rest_spec/ingest_setup.ts
index 33d1d227771839..17f4023fc8bead 100644
--- a/x-pack/plugins/canvas/public/components/palette_picker/index.js
+++ b/x-pack/plugins/ingest_manager/common/types/rest_spec/ingest_setup.ts
@@ -4,8 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { pure } from 'recompose';
-
-import { PalettePicker as Component } from './palette_picker';
-
-export const PalettePicker = pure(Component);
+export interface PostIngestSetupResponse {
+ isInitialized: boolean;
+}
diff --git a/x-pack/plugins/ingest_manager/public/plugin.ts b/x-pack/plugins/ingest_manager/public/plugin.ts
index 3eb2fad339b7d0..1cd70f70faa379 100644
--- a/x-pack/plugins/ingest_manager/public/plugin.ts
+++ b/x-pack/plugins/ingest_manager/public/plugin.ts
@@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n';
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../../src/plugins/data/public';
import { LicensingPluginSetup } from '../../licensing/public';
-import { PLUGIN_ID } from '../common/constants';
+import { PLUGIN_ID, CheckPermissionsResponse, PostIngestSetupResponse } from '../common';
import { IngestManagerConfigType } from '../common/types';
import { setupRouteService, appRoutesService } from '../common';
@@ -28,10 +28,7 @@ export type IngestManagerSetup = void;
*/
export interface IngestManagerStart {
registerDatasource: typeof registerDatasource;
- success: boolean;
- error?: {
- message: string;
- };
+ success: Promise;
}
export interface IngestManagerSetupDeps {
@@ -78,21 +75,29 @@ export class IngestManagerPlugin
}
public async start(core: CoreStart): Promise {
+ let successPromise: IngestManagerStart['success'];
try {
- const permissionsResponse = await core.http.get(appRoutesService.getCheckPermissionsPath());
- if (permissionsResponse.success) {
- const { isInitialized: success } = await core.http.post(setupRouteService.getSetupPath());
- return { success, registerDatasource };
+ const permissionsResponse = await core.http.get(
+ appRoutesService.getCheckPermissionsPath()
+ );
+
+ if (permissionsResponse?.success) {
+ successPromise = core.http
+ .post(setupRouteService.getSetupPath())
+ .then(({ isInitialized }) =>
+ isInitialized ? Promise.resolve(true) : Promise.reject(new Error('Unknown setup error'))
+ );
} else {
- throw new Error(permissionsResponse.error);
+ throw new Error(permissionsResponse?.error || 'Unknown permissions error');
}
} catch (error) {
- return {
- success: false,
- error: { message: error.body?.message || 'Unknown error' },
- registerDatasource,
- };
+ successPromise = Promise.reject(error);
}
+
+ return {
+ success: successPromise,
+ registerDatasource,
+ };
}
public stop() {}
diff --git a/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts
index 98083434173908..1daa63800f4ee5 100644
--- a/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts
+++ b/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts
@@ -6,7 +6,7 @@
import { RequestHandler } from 'src/core/server';
import { TypeOf } from '@kbn/config-schema';
import { outputService, appContextService } from '../../services';
-import { GetFleetStatusResponse } from '../../../common';
+import { GetFleetStatusResponse, PostIngestSetupResponse } from '../../../common';
import { setupIngestManager, setupFleet } from '../../services/setup';
import { PostFleetSetupRequestSchema } from '../../types';
import { IngestManagerError, getHTTPResponseCode } from '../../errors';
@@ -83,9 +83,10 @@ export const ingestManagerSetupHandler: RequestHandler = async (context, request
const callCluster = context.core.elasticsearch.legacy.client.callAsCurrentUser;
const logger = appContextService.getLogger();
try {
+ const body: PostIngestSetupResponse = { isInitialized: true };
await setupIngestManager(soClient, callCluster);
return response.ok({
- body: { isInitialized: true },
+ body,
});
} catch (e) {
if (e instanceof IngestManagerError) {
diff --git a/x-pack/plugins/security_solution/public/app/home/setup.tsx b/x-pack/plugins/security_solution/public/app/home/setup.tsx
index 5b977a83302a97..bf7ce2ddf8b509 100644
--- a/x-pack/plugins/security_solution/public/app/home/setup.tsx
+++ b/x-pack/plugins/security_solution/public/app/home/setup.tsx
@@ -32,20 +32,7 @@ export const Setup: React.FunctionComponent<{
});
};
- const displayToast = () => {
- notifications.toasts.addDanger({
- title,
- text: defaultText,
- });
- };
-
- if (!ingestManager.success) {
- if (ingestManager.error) {
- displayToastWithModal(ingestManager.error.message);
- } else {
- displayToast();
- }
- }
+ ingestManager.success.catch((error: Error) => displayToastWithModal(error.message));
}, [ingestManager, notifications.toasts]);
return null;
diff --git a/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts b/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts
index 759ec45c7e54be..f2e8d045eccf9f 100644
--- a/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts
+++ b/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts
@@ -56,6 +56,6 @@ export const depsStartMock: () => DepsStartMock = () => {
return {
data: dataMock,
- ingestManager: { success: true, registerDatasource },
+ ingestManager: { success: Promise.resolve(true), registerDatasource },
};
};
diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
index 199d138d1c450a..d94ee260b27820 100644
--- a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
+++ b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
@@ -5,10 +5,13 @@
*/
import { FtrProviderContext } from '../../ftr_provider_context';
-export default function ({ loadTestFile }: FtrProviderContext) {
+export default function ({ loadTestFile, getService }: FtrProviderContext) {
describe('endpoint', function () {
this.tags('ciGroup7');
-
+ const ingestManager = getService('ingestManager');
+ before(async () => {
+ await ingestManager.setup();
+ });
loadTestFile(require.resolve('./endpoint_list'));
loadTestFile(require.resolve('./policy_list'));
loadTestFile(require.resolve('./policy_details'));
diff --git a/x-pack/test/security_solution_endpoint/services/index.ts b/x-pack/test/security_solution_endpoint/services/index.ts
index 0247d9b00968a1..90b4bc0b4d0457 100644
--- a/x-pack/test/security_solution_endpoint/services/index.ts
+++ b/x-pack/test/security_solution_endpoint/services/index.ts
@@ -4,10 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { services as apiIntegrationServices } from '../../api_integration/services';
import { services as xPackFunctionalServices } from '../../functional/services';
import { EndpointPolicyTestResourcesProvider } from './endpoint_policy';
export const services = {
...xPackFunctionalServices,
+ ingestManager: apiIntegrationServices.ingestManager,
policyTestResources: EndpointPolicyTestResourcesProvider,
};