[Discover] Move truncate-by-height into Discover (#114320)

* [Discover] move source field formatter to discover

* [Discover] cleanup source field from field formatters

* [Discover] return source field format

* [Discover] move truncate by height to discover settings category, apply css via emotion

* [Discover] improve code readability, fix i18n

* [Discover] fix remaining i18n

* [Discover] fix unit tests

* [Discover] return truncate-by-height setting to general

* [Discover] return i18n naming

* [Discover] apply suggestions

* [Discover] fix i18n

* Update src/plugins/discover/server/ui_settings.ts

Co-authored-by: Matthias Wilhelm <ankertal@gmail.com>

* [Discover] fix embeddable and discover grid truncation styles

* [Discover] fix tests

* [Discover] get rid of emotion

* [Discover] apply suggestions

* [Discover] inject emotion styles properly

* [Discover] remove console.log

* [Discover] revert react router changes

* [Discover] fix truncate max height reset

* [Discover] simplify

* [Discover] return injection to the right place

* [Discover] remove unused import

* [Discover] apply suggestions

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Matthias Wilhelm <ankertal@gmail.com>
This commit is contained in:
Dmitry Tomashevich 2021-11-04 17:29:22 +03:00 committed by GitHub
parent 3a096788d2
commit c7866c360b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 116 additions and 93 deletions

View file

@ -111,7 +111,10 @@
"@elastic/request-crypto": "1.1.4",
"@elastic/safer-lodash-set": "link:bazel-bin/packages/elastic-safer-lodash-set",
"@elastic/search-ui-app-search-connector": "^1.6.0",
"@emotion/cache": "^11.4.0",
"@emotion/css": "^11.4.0",
"@emotion/react": "^11.4.0",
"@emotion/serialize": "^1.0.2",
"@hapi/accept": "^5.0.2",
"@hapi/boom": "^9.1.4",
"@hapi/cookie": "^11.0.2",

View file

@ -1,31 +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
* 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 { UiSettingsParams } from '../../../types';
import { getMiscUiSettings } from './misc';
describe('misc settings', () => {
const miscSettings = getMiscUiSettings();
const getValidationFn = (setting: UiSettingsParams) => (value: any) =>
setting.schema.validate(value);
describe('truncate:maxHeight', () => {
const validate = getValidationFn(miscSettings['truncate:maxHeight']);
it('should only accept positive numeric values', () => {
expect(() => validate(127)).not.toThrow();
expect(() => validate(-12)).toThrowErrorMatchingInlineSnapshot(
`"Value must be equal to or greater than [0]."`
);
expect(() => validate('foo')).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [number] but got [string]"`
);
});
});
});

View file

@ -6,23 +6,11 @@
* Side Public License, v 1.
*/
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
import { UiSettingsParams } from '../types';
export const getMiscUiSettings = (): Record<string, UiSettingsParams> => {
return {
'truncate:maxHeight': {
name: i18n.translate('core.ui_settings.params.maxCellHeightTitle', {
defaultMessage: 'Maximum table cell height',
}),
value: 115,
description: i18n.translate('core.ui_settings.params.maxCellHeightText', {
defaultMessage:
'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation',
}),
schema: schema.number({ min: 0 }),
},
buildNum: {
readonly: true,
schema: schema.maybe(schema.number()),

View file

@ -21,4 +21,5 @@ export const SEARCH_FIELDS_FROM_SOURCE = 'discover:searchFieldsFromSource';
export const MAX_DOC_FIELDS_DISPLAYED = 'discover:maxDocFieldsDisplayed';
export const SHOW_FIELD_STATISTICS = 'discover:showFieldStatistics';
export const SHOW_MULTIFIELDS = 'discover:showMultiFields';
export const TRUNCATE_MAX_HEIGHT = 'truncate:maxHeight';
export const SEARCH_EMBEDDABLE_TYPE = 'search';

View file

@ -103,10 +103,6 @@
text-align: center;
}
.truncate-by-height {
overflow: hidden;
}
.table {
// Nesting
.table {

View file

@ -88,7 +88,7 @@ export const TableRow = ({
return (
// formatFieldValue always returns sanitized HTML
// eslint-disable-next-line react/no-danger
<div className="truncate-by-height" dangerouslySetInnerHTML={{ __html: formattedField }} />
<div className="dscTruncateByHeight" dangerouslySetInnerHTML={{ __html: formattedField }} />
);
};
const inlineFilter = useCallback(

View file

@ -20,7 +20,7 @@ interface Props {
}
const TemplateComponent = ({ defPairs }: Props) => {
return (
<dl className={'source truncate-by-height'}>
<dl className={'source dscTruncateByHeight'}>
{defPairs.map((pair, idx) => (
<Fragment key={idx}>
<dt>{pair[0]}:</dt>

View file

@ -236,7 +236,7 @@ describe('DocViewTable at Discover Context', () => {
const btn = findTestSubject(component, `collapseBtn`);
const html = component.html();
expect(component.html()).toContain('truncate-by-height');
expect(component.html()).toContain('dscTruncateByHeight');
expect(btn.length).toBe(1);
btn.simulate('click');

View file

@ -104,7 +104,7 @@ export const TableFieldValue = ({
const valueClassName = classNames({
// eslint-disable-next-line @typescript-eslint/naming-convention
kbnDocViewer__value: true,
'truncate-by-height': isCollapsible && isCollapsed,
dscTruncateByHeight: isCollapsible && isCollapsed,
});
const onToggleCollapse = () => setFieldOpen((fieldOpenPrev) => !fieldOpenPrev);

View file

@ -22,6 +22,7 @@ export const discoverRouter = (services: DiscoverServices, history: History) =>
services,
history,
};
return (
<KibanaContextProvider services={services}>
<Router history={history} data-test-subj="discover-react-router">

View file

@ -0,0 +1,51 @@
/*
* 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 createCache from '@emotion/cache';
import { cache } from '@emotion/css';
import { serializeStyles } from '@emotion/serialize';
/**
* The following emotion cache management was introduced here
* https://ntsim.uk/posts/how-to-update-or-remove-global-styles-in-emotion/
*/
const TRUNCATE_GRADIENT_HEIGHT = 15;
const globalThemeCache = createCache({ key: 'truncation' });
const buildStylesheet = (maxHeight: number) => {
return [
`
.dscTruncateByHeight {
overflow: hidden;
max-height: ${maxHeight}px !important;
display: inline-block;
}
.dscTruncateByHeight:before {
top: ${maxHeight - TRUNCATE_GRADIENT_HEIGHT}px;
}
`,
];
};
const flushThemedGlobals = () => {
globalThemeCache.sheet.flush();
globalThemeCache.inserted = {};
globalThemeCache.registered = {};
};
export const injectTruncateStyles = (maxHeight: number) => {
if (maxHeight <= 0) {
flushThemedGlobals();
return;
}
const serialized = serializeStyles(buildStylesheet(maxHeight), cache.registered);
if (!globalThemeCache.inserted[serialized.name]) {
globalThemeCache.insert('', serialized, globalThemeCache.sheet, true);
}
};

View file

@ -62,6 +62,8 @@ import { DeferredSpinner } from './shared';
import { ViewSavedSearchAction } from './application/embeddable/view_saved_search_action';
import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public';
import { FieldFormatsStart } from '../../field_formats/public';
import { injectTruncateStyles } from './application/helpers/truncate_styles';
import { TRUNCATE_MAX_HEIGHT } from '../common';
declare module '../../share/public' {
export interface UrlGeneratorStateMapping {
@ -413,6 +415,8 @@ export class DiscoverPlugin
const services = buildServices(core, plugins, this.initializerContext);
setServices(services);
injectTruncateStyles(services.uiSettings.get(TRUNCATE_MAX_HEIGHT));
return {
urlGenerator: this.urlGenerator,
locator: this.locator,

View file

@ -26,6 +26,7 @@ import {
SEARCH_FIELDS_FROM_SOURCE,
MAX_DOC_FIELDS_DISPLAYED,
SHOW_MULTIFIELDS,
TRUNCATE_MAX_HEIGHT,
SHOW_FIELD_STATISTICS,
} from '../common';
@ -241,4 +242,16 @@ export const getUiSettings: () => Record<string, UiSettingsParams> = () => ({
category: ['discover'],
schema: schema.boolean(),
},
[TRUNCATE_MAX_HEIGHT]: {
name: i18n.translate('discover.advancedSettings.params.maxCellHeightTitle', {
defaultMessage: 'Maximum table cell height',
}),
value: 115,
category: ['discover'],
description: i18n.translate('discover.advancedSettings.params.maxCellHeightText', {
defaultMessage:
'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation',
}),
schema: schema.number({ min: 0 }),
},
});

View file

@ -25,7 +25,6 @@ export {
NumberFormat,
PercentFormat,
RelativeDateFormat,
SourceFormat,
StaticLookupFormat,
UrlFormat,
StringFormat,

View file

@ -6,16 +6,14 @@
* Side Public License, v 1.
*/
import { CoreStart, CoreSetup } from 'kibana/public';
import { injectHeaderStyle } from './utils/inject_header_style';
import type { CoreSetup } from 'kibana/public';
export class KibanaLegacyPlugin {
public setup(core: CoreSetup<{}, KibanaLegacyStart>) {
return {};
}
public start({ uiSettings }: CoreStart) {
injectHeaderStyle(uiSettings);
public start() {
return {
/**
* Loads the font-awesome icon font. Should be removed once the last consumer has migrated to EUI

View file

@ -1,32 +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
* 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 { IUiSettingsClient } from 'kibana/public';
export function buildCSS(maxHeight = 0, truncateGradientHeight = 15) {
return `
.truncate-by-height {
max-height: ${maxHeight > 0 ? `${maxHeight}px !important` : 'none'};
display: inline-block;
}
.truncate-by-height:before {
top: ${maxHeight > 0 ? maxHeight - truncateGradientHeight : truncateGradientHeight * -1}px;
}
`;
}
export function injectHeaderStyle(uiSettings: IUiSettingsClient) {
const style = document.createElement('style');
style.setAttribute('id', 'style-compile');
document.getElementsByTagName('head')[0].appendChild(style);
uiSettings.get$('truncate:maxHeight').subscribe((value: number) => {
// eslint-disable-next-line no-unsanitized/property
style.innerHTML = buildCSS(value);
});
}

View file

@ -1311,8 +1311,6 @@
"core.ui_settings.params.defaultRoute.defaultRouteTitle": "デフォルトのルート",
"core.ui_settings.params.disableAnimationsText": "Kibana UIの不要なアニメーションをオフにします。変更を適用するにはページを更新してください。",
"core.ui_settings.params.disableAnimationsTitle": "アニメーションを無効にする",
"core.ui_settings.params.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します",
"core.ui_settings.params.maxCellHeightTitle": "表のセルの高さの上限",
"core.ui_settings.params.notifications.banner.markdownLinkText": "マークダウン対応",
"core.ui_settings.params.notifications.bannerLifetimeText": "バナー通知が画面に表示される時間(ミリ秒単位)です。",
"core.ui_settings.params.notifications.bannerLifetimeTitle": "バナー通知時間",
@ -2315,6 +2313,8 @@
"discover.advancedSettings.sortDefaultOrderTitle": "デフォルトの並べ替え方向",
"discover.advancedSettings.sortOrderAsc": "昇順",
"discover.advancedSettings.sortOrderDesc": "降順",
"discover.advancedSettings.params.maxCellHeightTitle": "表のセルの高さの上限",
"discover.advancedSettings.params.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します",
"discover.backToTopLinkText": "最上部へ戻る。",
"discover.badge.readOnly.text": "読み取り専用",
"discover.badge.readOnly.tooltip": "検索を保存できません",

View file

@ -1327,8 +1327,6 @@
"core.ui_settings.params.defaultRoute.defaultRouteTitle": "默认路由",
"core.ui_settings.params.disableAnimationsText": "在 Kibana UI 中关闭所有不必要的动画。刷新页面可应用所做的更改。",
"core.ui_settings.params.disableAnimationsTitle": "禁用动画",
"core.ui_settings.params.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断",
"core.ui_settings.params.maxCellHeightTitle": "最大表单元格高度",
"core.ui_settings.params.notifications.banner.markdownLinkText": "Markdown 受支持",
"core.ui_settings.params.notifications.bannerLifetimeText": "在屏幕上显示横幅通知的时间(毫秒)。",
"core.ui_settings.params.notifications.bannerLifetimeTitle": "横幅通知生存时间",
@ -2337,6 +2335,8 @@
"discover.advancedSettings.sortDefaultOrderTitle": "默认排序方向",
"discover.advancedSettings.sortOrderAsc": "升序",
"discover.advancedSettings.sortOrderDesc": "降序",
"discover.advancedSettings.params.maxCellHeightTitle": "最大表单元格高度",
"discover.advancedSettings.params.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断",
"discover.backToTopLinkText": "返回顶部。",
"discover.badge.readOnly.text": "只读",
"discover.badge.readOnly.tooltip": "无法保存搜索",

View file

@ -2592,7 +2592,7 @@
dependencies:
"@babel/plugin-syntax-jsx" "^7.2.0"
"@emotion/babel-plugin@^11.2.0":
"@emotion/babel-plugin@^11.0.0", "@emotion/babel-plugin@^11.2.0":
version "11.2.0"
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.2.0.tgz#f25c6df8ec045dad5ae6ca63df0791673b98c920"
integrity sha512-lsnQBnl3l4wu/FJoyHnYRpHJeIPNkOBMbtDUIXcO8luulwRKZXPvA10zd2eXVN6dABIWNX4E34en/jkejIg/yA==
@ -2653,6 +2653,17 @@
"@emotion/weak-memoize" "^0.2.5"
stylis "^4.0.3"
"@emotion/cache@^11.5.0":
version "11.5.0"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.5.0.tgz#a5eb78cbef8163939ee345e3ddf0af217b845e62"
integrity sha512-mAZ5QRpLriBtaj/k2qyrXwck6yeoz1V5lMt/jfj6igWU35yYlNKs2LziXVgvH81gnJZ+9QQNGelSsnuoAy6uIw==
dependencies:
"@emotion/memoize" "^0.7.4"
"@emotion/sheet" "^1.0.3"
"@emotion/utils" "^1.0.0"
"@emotion/weak-memoize" "^0.2.5"
stylis "^4.0.10"
"@emotion/core@^10.0.9", "@emotion/core@^10.1.1":
version "10.1.1"
resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3"
@ -2682,6 +2693,17 @@
"@emotion/utils" "0.11.3"
babel-plugin-emotion "^10.0.27"
"@emotion/css@^11.4.0":
version "11.5.0"
resolved "https://registry.yarnpkg.com/@emotion/css/-/css-11.5.0.tgz#0a80017080cb44d47994fe576b9923bfc8b0f6ad"
integrity sha512-mqjz/3aqR9rp40M+pvwdKYWxlQK4Nj3cnNjo3Tx6SM14dSsEn7q/4W2/I7PlgG+mb27iITHugXuBIHH/QwUBVQ==
dependencies:
"@emotion/babel-plugin" "^11.0.0"
"@emotion/cache" "^11.5.0"
"@emotion/serialize" "^1.0.0"
"@emotion/sheet" "^1.0.3"
"@emotion/utils" "^1.0.0"
"@emotion/hash@0.8.0", "@emotion/hash@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
@ -2780,6 +2802,11 @@
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.1.tgz#245f54abb02dfd82326e28689f34c27aa9b2a698"
integrity sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g==
"@emotion/sheet@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.3.tgz#00c326cd7985c5ccb8fe2c1b592886579dcfab8f"
integrity sha512-YoX5GyQ4db7LpbmXHMuc8kebtBGP6nZfRC5Z13OKJMixBEwdZrJ914D6yJv/P+ZH/YY3F5s89NYX2hlZAf3SRQ==
"@emotion/styled-base@^10.0.27":
version "10.0.31"
resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.0.31.tgz#940957ee0aa15c6974adc7d494ff19765a2f742a"
@ -27271,6 +27298,11 @@ stylis@^3.5.0:
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
stylis@^4.0.10:
version "4.0.10"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
stylis@^4.0.3:
version "4.0.7"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.7.tgz#412a90c28079417f3d27c028035095e4232d2904"