Skip to content

Commit

Permalink
Merge branch 'main' into eui/v-72.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
1Copenut authored Jan 3, 2023
2 parents b34841a + 37a6636 commit e665457
Show file tree
Hide file tree
Showing 47 changed files with 1,038 additions and 1,111 deletions.
3 changes: 3 additions & 0 deletions examples/controls_example/public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { AppMountParameters } from '@kbn/core/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
import { ControlsExampleStartDeps } from './plugin';
import { BasicReduxExample } from './basic_redux_example';
import { EditExample } from './edit_example';
import { SearchExample } from './search_example';

export const renderApp = async (
Expand All @@ -26,6 +27,8 @@ export const renderApp = async (
<>
<SearchExample dataView={dataViews[0]} navigation={navigation} data={data} />
<EuiSpacer size="xl" />
<EditExample />
<EuiSpacer size="xl" />
<BasicReduxExample dataViewId={dataViews[0].id!} />
</>
) : (
Expand Down
122 changes: 122 additions & 0 deletions examples/controls_example/public/edit_example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React, { useState } from 'react';
import {
EuiButton,
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiLoadingContent,
EuiPanel,
EuiSpacer,
EuiText,
EuiTitle,
} from '@elastic/eui';
import { ViewMode } from '@kbn/embeddable-plugin/public';
import { LazyControlGroupRenderer, ControlGroupContainer } from '@kbn/controls-plugin/public';
import { withSuspense } from '@kbn/presentation-util-plugin/public';

const ControlGroupRenderer = withSuspense(LazyControlGroupRenderer);

const INPUT_KEY = 'kbnControls:saveExample:input';

export const EditExample = () => {
const [isSaving, setIsSaving] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [controlGroup, setControlGroup] = useState<ControlGroupContainer>();

async function onSave() {
setIsSaving(true);

localStorage.setItem(INPUT_KEY, JSON.stringify(controlGroup!.getInput()));

// simulated async save await
await new Promise((resolve) => setTimeout(resolve, 1000));

setIsSaving(false);
}

async function onLoad() {
setIsLoading(true);

// simulated async load await
await new Promise((resolve) => setTimeout(resolve, 1000));

let input = {};
const inputAsString = localStorage.getItem(INPUT_KEY);
if (inputAsString) {
try {
input = JSON.parse(inputAsString);
} catch (e) {
// ignore parse errors
}
}

setIsLoading(false);
return input;
}

return (
<>
<EuiTitle>
<h2>Edit and save example</h2>
</EuiTitle>
<EuiText>
<p>Customize controls and persist state to local storage.</p>
</EuiText>
<EuiSpacer size="m" />
<EuiPanel hasBorder={true}>
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
<EuiButtonEmpty
color="primary"
iconType="plusInCircle"
isDisabled={controlGroup === undefined}
onClick={() => {
controlGroup!.openAddDataControlFlyout();
}}
>
Add control
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
color="primary"
isDisabled={controlGroup === undefined || isSaving}
fill
onClick={onSave}
isLoading={isSaving}
>
Save
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
{isLoading ? (
<>
<EuiSpacer />
<EuiLoadingContent lines={1} />
</>
) : null}
<ControlGroupRenderer
getInitialInput={async (initialInput, builder) => {
const persistedInput = await onLoad();
return {
...initialInput,
...persistedInput,
viewMode: ViewMode.EDIT,
};
}}
onLoadComplete={async (newControlGroup) => {
setControlGroup(newControlGroup);
}}
/>
</EuiPanel>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import deepEqual from 'fast-deep-equal';
import { omit, isEqual } from 'lodash';
import { DEFAULT_SORT } from '../options_list/suggestions_sorting';
import { OPTIONS_LIST_DEFAULT_SORT } from '../options_list/suggestions_sorting';
import { OptionsListEmbeddableInput, OPTIONS_LIST_CONTROL } from '../options_list/types';

import { ControlPanelState } from './types';
Expand Down Expand Up @@ -65,7 +65,7 @@ export const ControlPanelDiffSystems: {
Boolean(singleSelectA) === Boolean(singleSelectB) &&
Boolean(existsSelectedA) === Boolean(existsSelectedB) &&
Boolean(runPastTimeoutA) === Boolean(runPastTimeoutB) &&
deepEqual(sortA ?? DEFAULT_SORT, sortB ?? DEFAULT_SORT) &&
deepEqual(sortA ?? OPTIONS_LIST_DEFAULT_SORT, sortB ?? OPTIONS_LIST_DEFAULT_SORT) &&
isEqual(selectedA ?? [], selectedB ?? []) &&
deepEqual(inputA, inputB)
);
Expand Down
8 changes: 7 additions & 1 deletion src/plugins/controls/common/options_list/mocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ const mockOptionsListComponentState = {
...getDefaultComponentState(),
field: undefined,
totalCardinality: 0,
availableOptions: ['woof', 'bark', 'meow', 'quack', 'moo'],
availableOptions: {
woof: { doc_count: 100 },
bark: { doc_count: 75 },
meow: { doc_count: 50 },
quack: { doc_count: 25 },
moo: { doc_count: 5 },
},
invalidSelections: [],
validSelections: [],
} as OptionsListComponentState;
Expand Down
11 changes: 6 additions & 5 deletions src/plugins/controls/common/options_list/suggestions_sorting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import { Direction } from '@elastic/eui';

export type OptionsListSortBy = '_count' | '_key';

export const DEFAULT_SORT: SortingType = { by: '_count', direction: 'desc' };
export const OPTIONS_LIST_DEFAULT_SORT: OptionsListSortingType = {
by: '_count',
direction: 'desc',
};

export const sortDirections: Readonly<Direction[]> = ['asc', 'desc'] as const;
export type SortDirection = typeof sortDirections[number];
export interface SortingType {
export interface OptionsListSortingType {
by: OptionsListSortBy;
direction: SortDirection;
direction: Direction;
}

export const getCompatibleSortingTypes = (type?: string): OptionsListSortBy[] => {
Expand Down
12 changes: 8 additions & 4 deletions src/plugins/controls/common/options_list/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@
import { FieldSpec, DataView, RuntimeFieldSpec } from '@kbn/data-views-plugin/common';
import type { Filter, Query, BoolQuery, TimeRange } from '@kbn/es-query';

import { SortingType } from './suggestions_sorting';
import { OptionsListSortingType } from './suggestions_sorting';
import { DataControlInput } from '../types';

export const OPTIONS_LIST_CONTROL = 'optionsListControl';

export interface OptionsListEmbeddableInput extends DataControlInput {
sort?: OptionsListSortingType;
selectedOptions?: string[];
existsSelected?: boolean;
runPastTimeout?: boolean;
singleSelect?: boolean;
hideExclude?: boolean;
hideExists?: boolean;
hideSort?: boolean;
sort?: SortingType;
exclude?: boolean;
}

Expand All @@ -32,11 +32,15 @@ export type OptionsListField = FieldSpec & {
childFieldName?: string;
};

export interface OptionsListSuggestions {
[key: string]: { doc_count: number };
}

/**
* The Options list response is returned from the serverside Options List route.
*/
export interface OptionsListResponse {
suggestions: string[];
suggestions: OptionsListSuggestions;
totalCardinality: number;
invalidSelections?: string[];
}
Expand All @@ -61,13 +65,13 @@ export type OptionsListRequest = Omit<
*/
export interface OptionsListRequestBody {
runtimeFieldMap?: Record<string, RuntimeFieldSpec>;
sort?: OptionsListSortingType;
filters?: Array<{ bool: BoolQuery }>;
selectedOptions?: string[];
runPastTimeout?: boolean;
parentFieldName?: string;
textFieldName?: string;
searchString?: string;
fieldSpec?: FieldSpec;
sort?: SortingType;
fieldName: string;
}
7 changes: 6 additions & 1 deletion src/plugins/controls/public/__stories__/controls.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ const storybookStubOptionsListRequest = async (
setTimeout(
() =>
r({
suggestions: getFlightSearchOptions(request.field.name, request.searchString),
suggestions: getFlightSearchOptions(request.field.name, request.searchString).reduce(
(o, current, index) => {
return { ...o, [current]: { doc_count: index } };
},
{}
),
totalCardinality: 100,
}),
120
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
import { i18n } from '@kbn/i18n';

export const ControlGroupStrings = {
getControlButtonTitle: () =>
i18n.translate('controls.controlGroup.toolbarButtonTitle', {
defaultMessage: 'Controls',
}),
emptyState: {
getBadge: () =>
i18n.translate('controls.controlGroup.emptyState.badgeText', {
Expand Down
Loading

0 comments on commit e665457

Please sign in to comment.