Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Id distribution issue #12

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/plugins/data/public/ui/filter_bar/filter_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,30 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {

const multipleFilters = [...props.multipleFilters];

const newMultipleFilters = multipleFilters.filter(
(filter) => filter.groupId !== Number(groupId)
const indexOfCurFilter = multipleFilters.findIndex(
(f) => Number(f.groupId) === Number(groupId)
);

const filtersNew = newMultipleFilters.concat(mergedFilters);
multipleFilters.splice(indexOfCurFilter, 1, ...mergedFilters);

// when user adds new filters in edit modal they should appear near of editing filter
let gId: number = 0;
let reserveGroupId: number;
const updatedMultipleFilters = multipleFilters.map((filter, idx) => {
if (filter.groupId !== reserveGroupId) {
reserveGroupId = filter.groupId;
gId++;
}
return {
...filter,
groupId: gId,
id: idx,
};
});

const filters = [...props.filters, ...buildFilters];
props?.onFiltersUpdated?.(filters);

props?.onMultipleFiltersUpdated?.(filtersNew);
props?.onMultipleFiltersUpdated?.(updatedMultipleFilters);

props.toggleEditFilterModal?.(false);
}
Expand Down Expand Up @@ -187,7 +201,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
labels.map((label) => {
// we should have same groupIds on our labeled filters group
gId = (groupedByAlias[label][0] as any).groupId;
groupedByAlias[label].forEach((filter) => ((filter as any).groupId = groupId));
groupedByAlias[label].forEach((filter) => ((filter as any).groupId = gId));
const labelBadge = (
<FilterExpressionItem
groupId={gId}
Expand Down Expand Up @@ -231,6 +245,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride}
initialAddFilterMode={undefined}
saveFilters={props.onFilterSave}
savedQueryService={props.savedQueryService}
/>
)}
</EuiFlexItem>
Expand Down
19 changes: 19 additions & 0 deletions src/plugins/data/public/ui/query_string_input/_query_bar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@
}
}

.kbnQueryBar__dataViewInput {
& .euiFormRow__labelWrapper {
width: fit-content;
color: $euiTitleColor;
background-color: $euiFormInputGroupLabelBackground;
margin-right: 0;
padding: 0 7px;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}

& .euiComboBox__inputWrap {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}

.kbnQueryBar__filterModalWrapper {
@media only screen and (min-width: map-get($euiBreakpoints, 'm')) {
& {
Expand Down Expand Up @@ -89,6 +106,7 @@
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}

&.kbnQueryBar__textarea--hasAppend {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
Expand All @@ -113,6 +131,7 @@
}

@include euiFormControlWithIcon($isIconOptional: true);

~ .euiFormControlLayoutIcons {
// By default form control layout icon is vertically centered, but our textarea
// can expand to be multi-line, so we position it with padding that matches
Expand Down
91 changes: 77 additions & 14 deletions src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* Side Public License, v 1.
*/

import React, { useState } from 'react';
import { groupBy } from 'lodash';
import React, { useCallback, useEffect, useState } from 'react';
import { groupBy, sortBy } from 'lodash';
import classNames from 'classnames';
import { Filter, buildFilter, buildCustomFilter, cleanFilter } from '@kbn/es-query';
import {
Expand All @@ -30,11 +30,12 @@ import {
EuiText,
EuiIcon,
EuiFieldText,
EuiBadge,
} from '@elastic/eui';
import { XJsonLang } from '@kbn/monaco';
import { i18n } from '@kbn/i18n';
import { CodeEditor } from '../../../../kibana_react/public';
import { getIndexPatternFromFilter } from '../../query';
import { getIndexPatternFromFilter, SavedQuery, SavedQueryService } from '../../query';
import {
getFilterableFields,
getOperatorOptions,
Expand Down Expand Up @@ -92,6 +93,7 @@ export function AddFilterModal({
savedQueryManagement,
initialAddFilterMode,
saveFilters,
savedQueryService,
}: {
onSubmit: (filters: Filter[]) => void;
onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void;
Expand All @@ -104,6 +106,7 @@ export function AddFilterModal({
savedQueryManagement?: JSX.Element;
initialAddFilterMode?: string;
saveFilters: (savedQueryMeta: SavedQueryMeta) => void;
savedQueryService: SavedQueryService;
}) {
const [selectedIndexPattern, setSelectedIndexPattern] = useState(
getIndexPatternFromFilter(filter, indexPatterns)
Expand All @@ -112,23 +115,70 @@ export function AddFilterModal({
const [customLabel, setCustomLabel] = useState<string>(filter.meta.alias || '');
const [queryDsl, setQueryDsl] = useState<string>(JSON.stringify(cleanFilter(filter), null, 2));
const [groupsCount, setGroupsCount] = useState<number>(1);
const [savedQueries, setSavedQueries] = useState<SavedQuery[]>([]);
const [submitDisabled, setSubmitDisabled] = useState(false);

const [localFilters, setLocalFilters] = useState<FilterGroup[]>([
{
field: undefined,
operator: undefined,
value: undefined,
groupId: multipleFilters?.length ? multipleFilters?.length + 1 : 1,
id: multipleFilters?.length ? multipleFilters?.length : 0,
// find the max groupId and id and start from + 1
groupId: multipleFilters?.length
? Math.max.apply(
Math,
multipleFilters.map((f) => f.groupId)
) + 1
: 1,
id: multipleFilters?.length
? Math.max.apply(
Math,
multipleFilters.map((f) => f.id)
) + 1
: 0,
subGroupId: 1,
relationship: undefined,
},
]);

useEffect(() => {
const fetchQueries = async () => {
const allSavedQueries = await savedQueryService.getAllSavedQueries();
const sortedAllSavedQueries = sortBy(allSavedQueries, 'attributes.title');
setSavedQueries(sortedAllSavedQueries);
};
fetchQueries();
}, [savedQueryService]);

const isLabelDuplicated = useCallback(
() =>
!!savedQueries.find(
(existingSavedQuery) => existingSavedQuery.attributes.title === customLabel
),
[savedQueries, customLabel]
);

const onIndexPatternChange = ([selectedPattern]: IIndexPattern[]) => {
setSelectedIndexPattern(selectedPattern);
setLocalFilters([
{ field: undefined, operator: undefined, value: undefined, groupId: 1, id: 0, subGroupId: 1 },
{
field: undefined,
operator: undefined,
value: undefined,
groupId: multipleFilters?.length
? Math.max.apply(
Math,
multipleFilters.map((f) => f.groupId)
) + 1
: 1,
id: multipleFilters?.length
? Math.max.apply(
Math,
multipleFilters.map((f) => f.id)
) + 1
: 0,
subGroupId: 1,
},
]);
setGroupsCount(1);
};
Expand Down Expand Up @@ -173,8 +223,9 @@ export function AddFilterModal({
<EuiFormRow
fullWidth
display="columnCompressed"
label={i18n.translate('data.filter.filterEditor.indexPatternSelectLabel', {
defaultMessage: 'Index pattern',
className="kbnQueryBar__dataViewInput"
label={i18n.translate('data.filter.filterEditor.dataViewSelectLabel', {
defaultMessage: 'Data view',
})}
>
<GenericComboBox
Expand Down Expand Up @@ -352,6 +403,12 @@ export function AddFilterModal({
return; // typescript validation
}
const alias = customLabel || null;
// validation for existence of saved filter with given alias
if (alias && isLabelDuplicated()) {
setSubmitDisabled(true);
return;
}

if (addFilterMode === 'query_builder') {
const { index, disabled = false, negate = false } = filter.meta;
const newIndex = index || indexPatterns[0].id!;
Expand Down Expand Up @@ -504,7 +561,7 @@ export function AddFilterModal({
const subGroupId =
filtersOnGroup.length > 2
? localfilter?.subGroupId ?? 0
: localfilter?.subGroupId ?? 0;
: (localfilter?.subGroupId ?? 0) + 1;
const updatedLocalFilter = {
...localfilter,
relationship: 'AND',
Expand All @@ -524,10 +581,8 @@ export function AddFilterModal({
relationship: undefined,
groupId:
filtersOnGroup.length > 1
? groupsCount
: Number(multipleFilters?.length) +
localFilters.length +
1,
? localFilters[localFilters.length - 1].groupId
: localFilters[localFilters.length - 1].groupId + 1,
subGroupId,
id: Number(multipleFilters?.length) + localFilters.length,
},
Expand Down Expand Up @@ -674,10 +729,17 @@ export function AddFilterModal({
defaultMessage: 'Label (optional)',
})}
display="columnCompressed"
error={i18n.translate('data.search.searchBar.savedQueryForm.titleConflictText', {
defaultMessage: 'Name conflicts with an existing saved query.',
})}
isInvalid={submitDisabled}
>
<EuiFieldText
value={`${customLabel}`}
onChange={(e) => setCustomLabel(e.target.value)}
onChange={(e) => {
setSubmitDisabled(false);
setCustomLabel(e.target.value);
}}
compressed
/>
</EuiFormRow>
Expand All @@ -698,6 +760,7 @@ export function AddFilterModal({
fill
onClick={onAddFilter}
data-test-subj="canvasCustomElementForm-submit"
disabled={submitDisabled}
>
{i18n.translate('data.filter.addFilterModal.addFilterBtnLabel', {
defaultMessage: 'Add filter',
Expand Down
Loading