Skip to content

Commit

Permalink
[Discover] View mapping conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
jughosta committed Oct 18, 2023
1 parent 69cfe3a commit 4f9afbe
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
EuiCallOut,
EuiCode,
EuiText,
EuiLink,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
Expand Down Expand Up @@ -67,8 +68,15 @@ const getCompositeRuntimeFields = (dataView: DataView) =>

export const EditIndexPattern = withRouter(
({ indexPattern, history, location }: EditIndexPatternProps) => {
const { uiSettings, overlays, chrome, dataViews, IndexPatternEditor, savedObjectsManagement } =
useKibana<IndexPatternManagmentContext>().services;
const {
uiSettings,
overlays,
chrome,
dataViews,
IndexPatternEditor,
savedObjectsManagement,
application,
} = useKibana<IndexPatternManagmentContext>().services;
const [fields, setFields] = useState<DataViewField[]>(indexPattern.getNonScriptedFields());
const [compositeRuntimeFields, setCompositeRuntimeFields] = useState<
Record<string, RuntimeField>
Expand Down Expand Up @@ -261,6 +269,20 @@ export const EditIndexPattern = withRouter(
<EuiSpacer />
<EuiCallOut title={mappingConflictHeader} color="warning" iconType="warning">
<p>{mappingConflictLabel}</p>
<EuiLink
href={application.getUrlForApp('management', {
path: `/kibana/dataViews/dataView/${encodeURIComponent(
indexPattern.id!
)}#/?_a=(fieldTypes:!(conflict),tab:indexedFields)`,
})}
>
{i18n.translate(
'indexPatternManagement.editIndexPattern.viewMappingConflictButton',
{
defaultMessage: 'View fields',
}
)}
</EuiLink>
</EuiCallOut>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {

interface IEditIndexPatternState {
tab: string;
fieldTypes?: string[];
}

/**
Expand Down Expand Up @@ -47,9 +48,14 @@ export function createEditIndexPatternPageStateContainer({
},
{
setTab: (state: IEditIndexPatternState) => (tab: string) => ({ ...state, tab }),
setFieldTypes: (state: IEditIndexPatternState) => (fieldTypes: string[]) => ({
...state,
fieldTypes: fieldTypes.length ? fieldTypes : undefined,
}),
},
{
tab: (state: IEditIndexPatternState) => () => state.tab,
fieldTypes: (state: IEditIndexPatternState) => () => state.fieldTypes,
}
);

Expand All @@ -71,5 +77,8 @@ export function createEditIndexPatternPageStateContainer({
stopSyncingState: stop,
setCurrentTab: (newTab: string) => stateContainer.transitions.setTab(newTab),
getCurrentTab: () => stateContainer.selectors.tab(),
setCurrentFieldTypes: (newFieldTypes: string[]) =>
stateContainer.transitions.setFieldTypes(newFieldTypes),
getCurrentFieldTypes: () => stateContainer.selectors.fieldTypes(),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Side Public License, v 1.
*/

import { uniq } from 'lodash';
import React, { useState, useCallback, useEffect, Fragment, useMemo, useRef } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import {
Expand Down Expand Up @@ -163,8 +164,11 @@ export function Tabs({
const [syncingStateFunc, setSyncingStateFunc] = useState<{
getCurrentTab: () => string;
setCurrentTab?: (newTab: string) => { tab: string };
getCurrentFieldTypes: () => string[] | undefined;
setCurrentFieldTypes?: (newFieldTypes: string[]) => { fieldTypes: string[] | undefined };
}>({
getCurrentTab: () => TAB_INDEXED_FIELDS,
getCurrentFieldTypes: () => [],
});
const [scriptedFieldLanguageFilter, setScriptedFieldLanguageFilter] = useState<string[]>([]);
const [isScriptedFieldFilterOpen, setIsScriptedFieldFilterOpen] = useState(false);
Expand All @@ -187,6 +191,22 @@ export function Tabs({
const closeEditorHandler = useRef<() => void | undefined>();
const { DeleteRuntimeFieldProvider } = dataViewFieldEditor;

const filteredIndexedFieldTypeFilter = useMemo(() => {
return uniq(
indexedFieldTypeFilter.filter((fieldType) =>
indexedFieldTypes.some((item) => item.value === fieldType)
)
);
}, [indexedFieldTypeFilter, indexedFieldTypes]);

const updateFieldTypeFilter = useCallback(
(newIndexedFieldTypeFilter: string[]) => {
setIndexedFieldTypeFilter(newIndexedFieldTypeFilter);
syncingStateFunc?.setCurrentFieldTypes?.(newIndexedFieldTypeFilter);
},
[setIndexedFieldTypeFilter, syncingStateFunc]
);

const updateFilterItem = (
items: FilterItems[],
index: number,
Expand Down Expand Up @@ -299,36 +319,36 @@ export function Tabs({
onClick={() => setIsIndexedFilterOpen(!isIndexedFilterOpen)}
isSelected={isIndexedFilterOpen}
numFilters={indexedFieldTypes.length}
hasActiveFilters={!!indexedFieldTypes.find((item) => item.checked === 'on')}
numActiveFilters={
indexedFieldTypes.filter((item) => item.checked === 'on').length
}
hasActiveFilters={filteredIndexedFieldTypeFilter.length > 0}
numActiveFilters={filteredIndexedFieldTypeFilter.length}
>
{filterLabel}
</EuiFilterButton>
}
isOpen={isIndexedFilterOpen}
closePopover={() => setIsIndexedFilterOpen(false)}
>
{indexedFieldTypes.map((item, index) => (
<EuiFilterSelectItem
checked={item.checked}
key={item.value}
onClick={() => {
setIndexedFieldTypeFilter(
item.checked
? indexedFieldTypeFilter.filter((f) => f !== item.value)
: [...indexedFieldTypeFilter, item.value]
);
updateFilterItem(indexedFieldTypes, index, setIndexedFieldTypes);
}}
data-test-subj={`indexedFieldTypeFilterDropdown-option-${item.value}${
item.checked ? '-checked' : ''
}`}
>
{item.name}
</EuiFilterSelectItem>
))}
{indexedFieldTypes.map((item, index) => {
const isSelected = filteredIndexedFieldTypeFilter.includes(item.value);
return (
<EuiFilterSelectItem
checked={isSelected ? 'on' : undefined}
key={item.value}
onClick={() => {
updateFieldTypeFilter(
isSelected
? filteredIndexedFieldTypeFilter.filter((f) => f !== item.value)
: [...filteredIndexedFieldTypeFilter, item.value]
);
}}
data-test-subj={`indexedFieldTypeFilterDropdown-option-${item.value}${
item.checked ? '-checked' : ''
}`}
>
{item.name}
</EuiFilterSelectItem>
);
})}
</EuiPopover>
<EuiPopover
anchorPosition="downCenter"
Expand Down Expand Up @@ -438,7 +458,7 @@ export function Tabs({
},
[
fieldFilter,
indexedFieldTypeFilter,
filteredIndexedFieldTypeFilter,
indexedFieldTypes,
isIndexedFilterOpen,
scriptedFieldLanguageFilter,
Expand All @@ -449,6 +469,7 @@ export function Tabs({
isSchemaFilterOpen,
openFieldEditor,
userEditPermission,
updateFieldTypeFilter,
]
);

Expand All @@ -469,7 +490,7 @@ export function Tabs({
indexPattern={indexPattern}
fieldFilter={fieldFilter}
fieldWildcardMatcher={fieldWildcardMatcherDecorated}
indexedFieldTypeFilter={indexedFieldTypeFilter}
indexedFieldTypeFilter={filteredIndexedFieldTypeFilter}
schemaFieldTypeFilter={schemaFieldTypeFilter}
helpers={{
editField: openFieldEditor,
Expand Down Expand Up @@ -547,7 +568,7 @@ export function Tabs({
getFilterSection,
history,
indexPattern,
indexedFieldTypeFilter,
filteredIndexedFieldTypeFilter,
schemaFieldTypeFilter,
refreshFilters,
scriptedFieldLanguageFilter,
Expand Down Expand Up @@ -583,18 +604,27 @@ export function Tabs({
const [selectedTabId, setSelectedTabId] = useState(euiTabs[0].id);

useEffect(() => {
const { startSyncingState, stopSyncingState, setCurrentTab, getCurrentTab } =
createEditIndexPatternPageStateContainer({
useHashedUrl: uiSettings.get('state:storeInSessionStorage'),
defaultTab: TAB_INDEXED_FIELDS,
});
const {
startSyncingState,
stopSyncingState,
setCurrentTab,
getCurrentTab,
setCurrentFieldTypes,
getCurrentFieldTypes,
} = createEditIndexPatternPageStateContainer({
useHashedUrl: uiSettings.get('state:storeInSessionStorage'),
defaultTab: TAB_INDEXED_FIELDS,
});

startSyncingState();
setSyncingStateFunc({
setCurrentTab,
getCurrentTab,
setCurrentFieldTypes,
getCurrentFieldTypes,
});
setSelectedTabId(getCurrentTab());
setIndexedFieldTypeFilter((currentValue) => getCurrentFieldTypes() || currentValue);

return () => {
stopSyncingState();
Expand Down

0 comments on commit 4f9afbe

Please sign in to comment.