Skip to content

Commit

Permalink
[Metrics UI] UX improvements for saved views (elastic#69910)
Browse files Browse the repository at this point in the history
* Works-ish

* Load the default view without throwing error

* Design feedback

* Update Saved Views design on Metrics explorer

* Fix types

* UX improvements when saving and editng

* Only load default view if there is no state from anywhere else.

* Add loading indicator and other polish

* Hide saved view menu when opening modals

* Fix typecheck

* Fix typo

* Fix translations
  • Loading branch information
phillipb authored and Bamieh committed Jul 1, 2020
1 parent adf11ec commit 3109588
Show file tree
Hide file tree
Showing 36 changed files with 1,023 additions and 215 deletions.
8 changes: 8 additions & 0 deletions x-pack/plugins/infra/common/graphql/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ export interface UpdateSourceInput {
logAlias?: string | null;
/** The field mapping to use for this source */
fields?: UpdateSourceFieldsInput | null;
/** Default view for inventory */
inventoryDefaultView?: string | null;
/** Default view for Metrics Explorer */
metricsExplorerDefaultView?: string | null;
/** The log columns to display for this source */
logColumns?: UpdateSourceLogColumnInput[] | null;
}
Expand Down Expand Up @@ -875,6 +879,10 @@ export namespace SourceConfigurationFields {
fields: Fields;

logColumns: LogColumns[];

inventoryDefaultView: string;

metricsExplorerDefaultView: string;
};

export type Fields = {
Expand Down
17 changes: 16 additions & 1 deletion x-pack/plugins/infra/common/http_api/source_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export const SavedSourceConfigurationRuntimeType = rt.partial({
description: rt.string,
metricAlias: rt.string,
logAlias: rt.string,
inventoryDefaultView: rt.string,
metricsExplorerDefaultView: rt.string,
fields: SavedSourceConfigurationFieldsRuntimeType,
logColumns: rt.array(SavedSourceConfigurationColumnRuntimeType),
});
Expand All @@ -79,14 +81,25 @@ export interface InfraSavedSourceConfiguration
export const pickSavedSourceConfiguration = (
value: InfraSourceConfiguration
): InfraSavedSourceConfiguration => {
const { name, description, metricAlias, logAlias, fields, logColumns } = value;
const {
name,
description,
metricAlias,
logAlias,
fields,
inventoryDefaultView,
metricsExplorerDefaultView,
logColumns,
} = value;
const { container, host, pod, tiebreaker, timestamp } = fields;

return {
name,
description,
metricAlias,
logAlias,
inventoryDefaultView,
metricsExplorerDefaultView,
fields: { container, host, pod, tiebreaker, timestamp },
logColumns,
};
Expand All @@ -106,6 +119,8 @@ export const StaticSourceConfigurationRuntimeType = rt.partial({
description: rt.string,
metricAlias: rt.string,
logAlias: rt.string,
inventoryDefaultView: rt.string,
metricsExplorerDefaultView: rt.string,
fields: StaticSourceConfigurationFieldsRuntimeType,
logColumns: rt.array(SavedSourceConfigurationColumnRuntimeType),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export const metricsExplorerViewSavedObjectType: SavedObjectsType = {
aggregation: {
type: 'keyword',
},
source: {
type: 'keyword',
},
},
},
chartOptions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ describe('ExpressionChart', () => {
logColumns: [],
metricAlias: 'metricbeat-*',
logAlias: 'filebeat-*',
inventoryDefaultView: 'host',
metricsExplorerDefaultView: 'host',
fields: {
timestamp: '@timestamp',
message: ['message'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { SavedView } from '../../hooks/use_saved_view';
import { SavedView } from '../../containers/saved_view/saved_view';

interface Props<ViewState> {
views: Array<SavedView<ViewState>>;
loading: boolean;
defaultViewId: string;
sourceIsLoading: boolean;
close(): void;
makeDefault(id: string): void;
setView(viewState: ViewState): void;
deleteView(id: string): void;
}

interface DeleteConfimationProps {
isDisabled?: boolean;
confirmedAction(): void;
}
const DeleteConfimation = (props: DeleteConfimationProps) => {
Expand All @@ -46,6 +50,7 @@ const DeleteConfimation = (props: DeleteConfimationProps) => {
<FormattedMessage defaultMessage="cancel" id="xpack.infra.waffle.savedViews.cancel" />
</EuiButtonEmpty>
<EuiButton
disabled={props.isDisabled}
fill={true}
iconType="trash"
color="danger"
Expand All @@ -64,13 +69,17 @@ const DeleteConfimation = (props: DeleteConfimationProps) => {
);
};

export function SavedViewListFlyout<ViewState>({
export function SavedViewManageViewsFlyout<ViewState>({
close,
views,
defaultViewId,
setView,
makeDefault,
deleteView,
loading,
sourceIsLoading,
}: Props<ViewState>) {
const [inProgressView, setInProgressView] = useState<string | null>(null);
const renderName = useCallback(
(name: string, item: SavedView<ViewState>) => (
<EuiButtonEmpty
Expand All @@ -89,6 +98,7 @@ export function SavedViewListFlyout<ViewState>({
(item: SavedView<ViewState>) => {
return (
<DeleteConfimation
isDisabled={item.isDefault}
confirmedAction={() => {
deleteView(item.id);
}}
Expand All @@ -98,6 +108,25 @@ export function SavedViewListFlyout<ViewState>({
[deleteView]
);

const renderMakeDefaultAction = useCallback(
(item: SavedView<ViewState>) => {
const isDefault = item.id === defaultViewId;
return (
<>
<EuiButtonEmpty
isLoading={inProgressView === item.id && sourceIsLoading}
iconType={isDefault ? 'starFilled' : 'starEmpty'}
onClick={() => {
setInProgressView(item.id);
makeDefault(item.id);
}}
/>
</>
);
},
[makeDefault, defaultViewId, sourceIsLoading, inProgressView]
);

const columns = [
{
field: 'name',
Expand All @@ -112,7 +141,11 @@ export function SavedViewListFlyout<ViewState>({
}),
actions: [
{
available: (item: SavedView<ViewState>) => !item.isDefault,
available: () => true,
render: renderMakeDefaultAction,
},
{
available: (item: SavedView<ViewState>) => true,
render: renderDeleteAction,
},
],
Expand All @@ -124,7 +157,10 @@ export function SavedViewListFlyout<ViewState>({
<EuiFlyoutHeader>
<EuiTitle size="m">
<h2>
<FormattedMessage defaultMessage="Load views" id="xpack.infra.openView.flyoutHeader" />
<FormattedMessage
defaultMessage="Manage saved views"
id="xpack.infra.openView.flyoutHeader"
/>
</h2>
</EuiTitle>
</EuiFlyoutHeader>
Expand Down
Loading

0 comments on commit 3109588

Please sign in to comment.