mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Discover] Hide multifields from doc table (#109242)
* [Discover] Hide multifields from doc table * Fix failing type check * Fix eslint * Fix faulty logic * Fix linting error * Add memoization to the function * Move getFieldsToShow a bit higher up * Extracting getFieldsToShow logic higher up * Fix linting error / table logic * Move fieldsToShow to doc_table_wrapper Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
c037e25071
commit
811d3d779f
11 changed files with 210 additions and 30 deletions
|
@ -35,6 +35,7 @@ export interface TableRowProps {
|
|||
hideTimeColumn: boolean;
|
||||
filterManager: FilterManager;
|
||||
addBasePath: (path: string) => string;
|
||||
fieldsToShow: string[];
|
||||
}
|
||||
|
||||
export const TableRow = ({
|
||||
|
@ -43,6 +44,7 @@ export const TableRow = ({
|
|||
row,
|
||||
indexPattern,
|
||||
useNewFieldsApi,
|
||||
fieldsToShow,
|
||||
hideTimeColumn,
|
||||
onAddColumn,
|
||||
onRemoveColumn,
|
||||
|
@ -125,7 +127,7 @@ export const TableRow = ({
|
|||
}
|
||||
|
||||
if (columns.length === 0 && useNewFieldsApi) {
|
||||
const formatted = formatRow(row, indexPattern);
|
||||
const formatted = formatRow(row, indexPattern, fieldsToShow);
|
||||
|
||||
rowCells.push(
|
||||
<TableCell
|
||||
|
|
|
@ -14,12 +14,14 @@ import { FORMATS_UI_SETTINGS } from '../../../../../../../field_formats/common';
|
|||
import {
|
||||
DOC_HIDE_TIME_COLUMN_SETTING,
|
||||
SAMPLE_SIZE_SETTING,
|
||||
SHOW_MULTIFIELDS,
|
||||
SORT_DEFAULT_ORDER_SETTING,
|
||||
} from '../../../../../../common';
|
||||
import { getServices, IndexPattern } from '../../../../../kibana_services';
|
||||
import { getServices, IndexPattern, IndexPatternField } from '../../../../../kibana_services';
|
||||
import { SortOrder } from './components/table_header/helpers';
|
||||
import { DocTableRow, TableRow } from './components/table_row';
|
||||
import { DocViewFilterFn } from '../../../../doc_views/doc_views_types';
|
||||
import { getFieldsToShow } from '../../../../helpers/get_fields_to_show';
|
||||
|
||||
export interface DocTableProps {
|
||||
/**
|
||||
|
@ -120,6 +122,7 @@ export const DocTableWrapper = ({
|
|||
hideTimeColumn,
|
||||
isShortDots,
|
||||
sampleSize,
|
||||
showMultiFields,
|
||||
filterManager,
|
||||
addBasePath,
|
||||
] = useMemo(() => {
|
||||
|
@ -129,6 +132,7 @@ export const DocTableWrapper = ({
|
|||
services.uiSettings.get(DOC_HIDE_TIME_COLUMN_SETTING, false),
|
||||
services.uiSettings.get(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE),
|
||||
services.uiSettings.get(SAMPLE_SIZE_SETTING, 500),
|
||||
services.uiSettings.get(SHOW_MULTIFIELDS, false),
|
||||
services.filterManager,
|
||||
services.addBasePath,
|
||||
];
|
||||
|
@ -149,6 +153,16 @@ export const DocTableWrapper = ({
|
|||
bottomMarker!.blur();
|
||||
}, [setMinimumVisibleRows, rows]);
|
||||
|
||||
const fieldsToShow = useMemo(
|
||||
() =>
|
||||
getFieldsToShow(
|
||||
indexPattern.fields.map((field: IndexPatternField) => field.name),
|
||||
indexPattern,
|
||||
showMultiFields
|
||||
),
|
||||
[indexPattern, showMultiFields]
|
||||
);
|
||||
|
||||
const renderHeader = useCallback(
|
||||
() => (
|
||||
<TableHeader
|
||||
|
@ -193,6 +207,7 @@ export const DocTableWrapper = ({
|
|||
onRemoveColumn={onRemoveColumn}
|
||||
filterManager={filterManager}
|
||||
addBasePath={addBasePath}
|
||||
fieldsToShow={fieldsToShow}
|
||||
/>
|
||||
));
|
||||
},
|
||||
|
@ -206,6 +221,7 @@ export const DocTableWrapper = ({
|
|||
onRemoveColumn,
|
||||
filterManager,
|
||||
addBasePath,
|
||||
fieldsToShow,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ describe('Row formatter', () => {
|
|||
|
||||
const indexPattern = createIndexPattern();
|
||||
|
||||
const fieldsToShow = indexPattern.fields.getAll().map((fld) => fld.name);
|
||||
|
||||
// Realistic response with alphabetical insertion order
|
||||
const formatHitReturnValue = {
|
||||
also: 'with \\"quotes\\" or 'single qoutes'',
|
||||
|
@ -69,7 +71,7 @@ describe('Row formatter', () => {
|
|||
});
|
||||
|
||||
it('formats document properly', () => {
|
||||
expect(formatRow(hit, indexPattern)).toMatchInlineSnapshot(`
|
||||
expect(formatRow(hit, indexPattern, fieldsToShow)).toMatchInlineSnapshot(`
|
||||
<TemplateComponent
|
||||
defPairs={
|
||||
Array [
|
||||
|
@ -113,7 +115,7 @@ describe('Row formatter', () => {
|
|||
get: () => 1,
|
||||
},
|
||||
} as unknown) as DiscoverServices);
|
||||
expect(formatRow(hit, indexPattern)).toMatchInlineSnapshot(`
|
||||
expect(formatRow(hit, indexPattern, [])).toMatchInlineSnapshot(`
|
||||
<TemplateComponent
|
||||
defPairs={
|
||||
Array [
|
||||
|
@ -128,7 +130,8 @@ describe('Row formatter', () => {
|
|||
});
|
||||
|
||||
it('formats document with highlighted fields first', () => {
|
||||
expect(formatRow({ ...hit, highlight: { number: '42' } }, indexPattern)).toMatchInlineSnapshot(`
|
||||
expect(formatRow({ ...hit, highlight: { number: '42' } }, indexPattern, fieldsToShow))
|
||||
.toMatchInlineSnapshot(`
|
||||
<TemplateComponent
|
||||
defPairs={
|
||||
Array [
|
||||
|
|
|
@ -29,8 +29,12 @@ const TemplateComponent = ({ defPairs }: Props) => {
|
|||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const formatRow = (hit: Record<string, any>, indexPattern: IndexPattern) => {
|
||||
export const formatRow = (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
hit: Record<string, any>,
|
||||
indexPattern: IndexPattern,
|
||||
fieldsToShow: string[]
|
||||
) => {
|
||||
const highlights = hit?.highlight ?? {};
|
||||
// Keys are sorted in the hits object
|
||||
const formatted = indexPattern.formatHit(hit);
|
||||
|
@ -40,7 +44,13 @@ export const formatRow = (hit: Record<string, any>, indexPattern: IndexPattern)
|
|||
Object.entries(formatted).forEach(([key, val]) => {
|
||||
const displayKey = fields.getByName ? fields.getByName(key)?.displayName : undefined;
|
||||
const pairs = highlights[key] ? highlightPairs : sourcePairs;
|
||||
pairs.push([displayKey ? displayKey : key, val]);
|
||||
if (displayKey) {
|
||||
if (fieldsToShow.includes(displayKey)) {
|
||||
pairs.push([displayKey, val]);
|
||||
}
|
||||
} else {
|
||||
pairs.push([key, val]);
|
||||
}
|
||||
});
|
||||
const maxEntries = getServices().uiSettings.get(MAX_DOC_FIELDS_DISPLAYED);
|
||||
return <TemplateComponent defPairs={[...highlightPairs, ...sourcePairs].slice(0, maxEntries)} />;
|
||||
|
|
|
@ -37,9 +37,10 @@ import { defaultPageSize, gridStyle, pageSizeArr, toolbarVisibility } from './co
|
|||
import { DiscoverServices } from '../../../build_services';
|
||||
import { getDisplayedColumns } from '../../helpers/columns';
|
||||
import { KibanaContextProvider } from '../../../../../kibana_react/public';
|
||||
import { MAX_DOC_FIELDS_DISPLAYED } from '../../../../common';
|
||||
import { MAX_DOC_FIELDS_DISPLAYED, SHOW_MULTIFIELDS } from '../../../../common';
|
||||
import { DiscoverGridDocumentToolbarBtn, getDocId } from './discover_grid_document_selection';
|
||||
import { SortPairArr } from '../../apps/main/components/doc_table/lib/get_sort';
|
||||
import { getFieldsToShow } from '../../helpers/get_fields_to_show';
|
||||
|
||||
interface SortObj {
|
||||
id: string;
|
||||
|
@ -256,6 +257,13 @@ export const DiscoverGrid = ({
|
|||
[onSort, isSortEnabled]
|
||||
);
|
||||
|
||||
const showMultiFields = services.uiSettings.get(SHOW_MULTIFIELDS);
|
||||
|
||||
const fieldsToShow = useMemo(() => {
|
||||
const indexPatternFields = indexPattern.fields.getAll().map((fld) => fld.name);
|
||||
return getFieldsToShow(indexPatternFields, indexPattern, showMultiFields);
|
||||
}, [indexPattern, showMultiFields]);
|
||||
|
||||
/**
|
||||
* Cell rendering
|
||||
*/
|
||||
|
@ -266,9 +274,10 @@ export const DiscoverGrid = ({
|
|||
displayedRows,
|
||||
displayedRows ? displayedRows.map((hit) => indexPattern.flattenHit(hit)) : [],
|
||||
useNewFieldsApi,
|
||||
fieldsToShow,
|
||||
services.uiSettings.get(MAX_DOC_FIELDS_DISPLAYED)
|
||||
),
|
||||
[displayedRows, indexPattern, useNewFieldsApi, services.uiSettings]
|
||||
[indexPattern, displayedRows, useNewFieldsApi, fieldsToShow, services.uiSettings]
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,6 +75,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsSource,
|
||||
rowsSource.map((row) => indexPatternMock.flattenHit(row)),
|
||||
false,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -96,6 +97,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsSource,
|
||||
rowsSource.map((row) => indexPatternMock.flattenHit(row)),
|
||||
false,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -146,6 +148,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsSource,
|
||||
rowsSource.map((row) => indexPatternMock.flattenHit(row)),
|
||||
false,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -188,6 +191,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsFields,
|
||||
rowsFields.map((row) => indexPatternMock.flattenHit(row)),
|
||||
true,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -242,6 +246,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsFields,
|
||||
rowsFields.map((row) => indexPatternMock.flattenHit(row)),
|
||||
true,
|
||||
[],
|
||||
// this is the number of rendered items
|
||||
1
|
||||
);
|
||||
|
@ -284,6 +289,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsFields,
|
||||
rowsFields.map((row) => indexPatternMock.flattenHit(row)),
|
||||
true,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -331,6 +337,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsFieldsWithTopLevelObject,
|
||||
rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)),
|
||||
true,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -371,6 +378,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsFieldsWithTopLevelObject,
|
||||
rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)),
|
||||
true,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -410,6 +418,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsFieldsWithTopLevelObject,
|
||||
rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)),
|
||||
true,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -440,6 +449,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsFieldsWithTopLevelObject,
|
||||
rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)),
|
||||
true,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -469,6 +479,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsSource,
|
||||
rowsSource.map((row) => indexPatternMock.flattenHit(row)),
|
||||
false,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
@ -490,6 +501,7 @@ describe('Discover grid cell rendering', function () {
|
|||
rowsSource,
|
||||
rowsSource.map((row) => indexPatternMock.flattenHit(row)),
|
||||
false,
|
||||
[],
|
||||
100
|
||||
);
|
||||
const component = shallow(
|
||||
|
|
|
@ -28,6 +28,7 @@ export const getRenderCellValueFn = (
|
|||
rows: ElasticSearchHit[] | undefined,
|
||||
rowsFlattened: Array<Record<string, unknown>>,
|
||||
useNewFieldsApi: boolean,
|
||||
fieldsToShow: string[],
|
||||
maxDocFieldsDisplayed: number
|
||||
) => ({ rowIndex, columnId, isDetails, setCellProps }: EuiDataGridCellValueElementProps) => {
|
||||
const row = rows ? rows[rowIndex] : undefined;
|
||||
|
@ -99,7 +100,13 @@ export const getRenderCellValueFn = (
|
|||
)
|
||||
.join(', ');
|
||||
const pairs = highlights[key] ? highlightPairs : sourcePairs;
|
||||
pairs.push([displayKey ? displayKey : key, formatted]);
|
||||
if (displayKey) {
|
||||
if (fieldsToShow.includes(displayKey)) {
|
||||
pairs.push([displayKey, formatted]);
|
||||
}
|
||||
} else {
|
||||
pairs.push([key, formatted]);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
|
@ -137,13 +144,18 @@ export const getRenderCellValueFn = (
|
|||
const highlights: Record<string, unknown> = (row.highlight as Record<string, unknown>) ?? {};
|
||||
const highlightPairs: Array<[string, string]> = [];
|
||||
const sourcePairs: Array<[string, string]> = [];
|
||||
|
||||
Object.entries(formatted).forEach(([key, val]) => {
|
||||
const pairs = highlights[key] ? highlightPairs : sourcePairs;
|
||||
const displayKey = indexPattern.fields.getByName
|
||||
? indexPattern.fields.getByName(key)?.displayName
|
||||
: undefined;
|
||||
pairs.push([displayKey ? displayKey : key, val as string]);
|
||||
if (displayKey) {
|
||||
if (fieldsToShow.includes(displayKey)) {
|
||||
pairs.push([displayKey, val as string]);
|
||||
}
|
||||
} else {
|
||||
pairs.push([key, val as string]);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
|
@ -475,11 +475,13 @@ describe('DocViewTable at Discover Doc with Fields API', () => {
|
|||
.length
|
||||
).toBe(0);
|
||||
|
||||
expect(findTestSubject(component, 'tableDocViewRow-customer_first_name').length).toBe(1);
|
||||
expect(
|
||||
findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname-multifieldBadge')
|
||||
.length
|
||||
).toBe(0);
|
||||
|
||||
expect(findTestSubject(component, 'tableDocViewRow-city').length).toBe(0);
|
||||
expect(findTestSubject(component, 'tableDocViewRow-city.raw').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { EuiInMemoryTable } from '@elastic/eui';
|
||||
import { IndexPattern, IndexPatternField } from '../../../../../data/public';
|
||||
import { SHOW_MULTIFIELDS } from '../../../../common';
|
||||
|
@ -18,6 +18,7 @@ import {
|
|||
DocViewRenderProps,
|
||||
} from '../../doc_views/doc_views_types';
|
||||
import { ACTIONS_COLUMN, MAIN_COLUMNS } from './table_columns';
|
||||
import { getFieldsToShow } from '../../helpers/get_fields_to_show';
|
||||
|
||||
export interface DocViewerTableProps {
|
||||
columns?: string[];
|
||||
|
@ -61,8 +62,6 @@ export const DocViewerTable = ({
|
|||
indexPattern?.fields,
|
||||
]);
|
||||
|
||||
const [childParentFieldsMap] = useState({} as Record<string, string>);
|
||||
|
||||
const formattedHit = useMemo(() => indexPattern?.formatHit(hit, 'html'), [hit, indexPattern]);
|
||||
|
||||
const tableColumns = useMemo(() => {
|
||||
|
@ -95,22 +94,12 @@ export const DocViewerTable = ({
|
|||
return null;
|
||||
}
|
||||
|
||||
const flattened = indexPattern.flattenHit(hit);
|
||||
Object.keys(flattened).forEach((key) => {
|
||||
const field = mapping(key);
|
||||
if (field && field.spec?.subType?.multi?.parent) {
|
||||
childParentFieldsMap[field.name] = field.spec.subType.multi.parent;
|
||||
}
|
||||
});
|
||||
const flattened = indexPattern?.flattenHit(hit);
|
||||
const fieldsToShow = getFieldsToShow(Object.keys(flattened), indexPattern, showMultiFields);
|
||||
|
||||
const items: FieldRecord[] = Object.keys(flattened)
|
||||
.filter((fieldName) => {
|
||||
const fieldMapping = mapping(fieldName);
|
||||
const isMultiField = !!fieldMapping?.spec?.subType?.multi;
|
||||
if (!isMultiField) {
|
||||
return true;
|
||||
}
|
||||
const parent = childParentFieldsMap[fieldName];
|
||||
return showMultiFields || (parent && !flattened.hasOwnProperty(parent));
|
||||
return fieldsToShow.includes(fieldName);
|
||||
})
|
||||
.sort((fieldA, fieldB) => {
|
||||
const mappingA = mapping(fieldA);
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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 { IndexPattern, IndexPatternField } from '../../../../data/common';
|
||||
import { getFieldsToShow } from './get_fields_to_show';
|
||||
|
||||
describe('get fields to show', () => {
|
||||
let indexPattern: IndexPattern;
|
||||
const indexPatternFields: Record<string, IndexPatternField> = {
|
||||
'machine.os': {
|
||||
name: 'machine.os',
|
||||
esTypes: ['text'],
|
||||
type: 'string',
|
||||
aggregatable: false,
|
||||
searchable: false,
|
||||
filterable: true,
|
||||
} as IndexPatternField,
|
||||
'machine.os.raw': {
|
||||
name: 'machine.os.raw',
|
||||
type: 'string',
|
||||
esTypes: ['keyword'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
filterable: true,
|
||||
spec: {
|
||||
subType: {
|
||||
multi: {
|
||||
parent: 'machine.os',
|
||||
},
|
||||
},
|
||||
},
|
||||
} as IndexPatternField,
|
||||
acknowledged: {
|
||||
name: 'acknowledged',
|
||||
type: 'boolean',
|
||||
esTypes: ['boolean'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
filterable: true,
|
||||
} as IndexPatternField,
|
||||
bytes: {
|
||||
name: 'bytes',
|
||||
type: 'number',
|
||||
esTypes: ['long'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
filterable: true,
|
||||
} as IndexPatternField,
|
||||
clientip: {
|
||||
name: 'clientip',
|
||||
type: 'ip',
|
||||
esTypes: ['ip'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
filterable: true,
|
||||
} as IndexPatternField,
|
||||
};
|
||||
const stubIndexPattern = {
|
||||
id: 'logstash-*',
|
||||
fields: Object.keys(indexPatternFields).map((key) => indexPatternFields[key]),
|
||||
title: 'logstash-*',
|
||||
timeFieldName: '@timestamp',
|
||||
getTimeField: () => ({ name: '@timestamp', type: 'date' }),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
indexPattern = stubIndexPattern as IndexPattern;
|
||||
indexPattern.fields.getByName = (name) => indexPatternFields[name];
|
||||
});
|
||||
|
||||
it('shows multifields when showMultiFields is true', () => {
|
||||
const fieldsToShow = getFieldsToShow(
|
||||
['machine.os', 'machine.os.raw', 'clientip'],
|
||||
indexPattern,
|
||||
true
|
||||
);
|
||||
expect(fieldsToShow).toEqual(['machine.os', 'machine.os.raw', 'clientip']);
|
||||
});
|
||||
|
||||
it('do not show multifields when showMultiFields is false', () => {
|
||||
const fieldsToShow = getFieldsToShow(
|
||||
['machine.os', 'machine.os.raw', 'acknowledged', 'clientip'],
|
||||
indexPattern,
|
||||
false
|
||||
);
|
||||
expect(fieldsToShow).toEqual(['machine.os', 'acknowledged', 'clientip']);
|
||||
});
|
||||
});
|
|
@ -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
|
||||
* 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 { IndexPattern } from '../../../../data/common';
|
||||
|
||||
export const getFieldsToShow = (
|
||||
fields: string[],
|
||||
indexPattern: IndexPattern,
|
||||
showMultiFields: boolean
|
||||
) => {
|
||||
const childParentFieldsMap = {} as Record<string, string>;
|
||||
const mapping = (name: string) => indexPattern.fields.getByName(name);
|
||||
fields.forEach((key) => {
|
||||
const mapped = mapping(key);
|
||||
if (mapped && mapped.spec?.subType?.multi?.parent) {
|
||||
childParentFieldsMap[mapped.name] = mapped.spec.subType.multi.parent;
|
||||
}
|
||||
});
|
||||
return fields.filter((key: string) => {
|
||||
const fieldMapping = mapping(key);
|
||||
const isMultiField = !!fieldMapping?.spec?.subType?.multi;
|
||||
if (!isMultiField) {
|
||||
return true;
|
||||
}
|
||||
const parent = childParentFieldsMap[key];
|
||||
return showMultiFields || (parent && !fields.includes(parent));
|
||||
});
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue