Skip to content

Commit

Permalink
Merge pull request elastic#13 from nlatipov/issue-create-edit-filter
Browse files Browse the repository at this point in the history
Issue create edit filter
  • Loading branch information
stratoula authored Feb 17, 2022
2 parents 9114140 + 621bcd8 commit 820d162
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 89 deletions.
101 changes: 66 additions & 35 deletions src/plugins/data/public/ui/filter_bar/filter_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
const groupRef = useRef<HTMLDivElement>(null);
const kibana = useKibana<IDataPluginServices>();
const { appName, usageCollection, uiSettings } = kibana.services;
const [groupId, setGroupId] = useState<number | null>(null);
const [groupIds, setGroupIds] = useState<[] | undefined>(undefined);
if (!uiSettings) return null;

const reportUiCounter = usageCollection?.reportUiCounter.bind(usageCollection, appName);
Expand All @@ -62,16 +62,18 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
}
}

const onEditFilterClick = (gId: number) => {
setGroupId(gId);
const onEditFilterClick = (groupIds: []) => {
setGroupIds(groupIds);
props.toggleEditFilterModal?.(true);
};

const onDeleteFilterGroup = (gId: string) => {
const onDeleteFilterGroup = () => {
const multipleFilters = [...props.multipleFilters];

const updatedMultipleFilters = multipleFilters.filter(
(filter) => filter.groupId !== Number(gId)
(filter) => !groupIds.includes(filter.groupId)
);

const filters = [...props.filters];
const updatedFilters: Filter[] = [];

Expand All @@ -95,7 +97,11 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
props?.onFiltersUpdated?.(filters);
}

function onEditMultipleFiltersANDOR(selectedFilters: FilterGroup[], buildFilters: Filter[]) {
function onEditMultipleFiltersANDOR(
selectedFilters: FilterGroup[],
buildFilters: Filter[],
groupCount: number
) {
const mappedFilters = mapAndFlattenFilters(buildFilters);
const mergedFilters = mappedFilters.map((filter, idx) => {
return {
Expand All @@ -104,35 +110,53 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
id: selectedFilters[idx].id,
relationship: selectedFilters[idx].relationship,
subGroupId: selectedFilters[idx].subGroupId,
groupCount
};
});

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

const indexOfCurFilter = multipleFilters.findIndex(
(f) => Number(f.groupId) === Number(groupId)
const newMultipleFilters = multipleFilters.filter(
(filter) => !groupIds.includes(filter.groupId)
);
multipleFilters.splice(indexOfCurFilter, 1, ...mergedFilters);

const filtersNew = newMultipleFilters.concat(mergedFilters);

// const indexOfCurFilter = multipleFilters.findIndex(
// (f) => Number(f.groupId) === Number(groupId)
// );

// 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,
};
});
// 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,
// };
// });

props?.onMultipleFiltersUpdated?.(filtersNew);

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

props?.onMultipleFiltersUpdated?.(updatedMultipleFilters);
filtersNew.forEach((filter) => {
filters.forEach((f) => {
if (isEqual(f.query, filter.query)) {
updatedFilters.push(f);
}
});
});

props?.onFiltersUpdated?.(updatedFilters);

props.toggleEditFilterModal?.(false);
}
Expand Down Expand Up @@ -197,14 +221,13 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
GroupBadge.push(badge);
}

let gId: string;
let groupId: string;
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 = gId));
groupId = (groupedByAlias[label][0] as any).groupId;
const labelBadge = (
<FilterExpressionItem
groupId={gId}
groupId={groupId}
groupedFilters={groupedByAlias[label]}
indexPatterns={props?.indexPatterns}
onClick={() => {}}
Expand All @@ -225,9 +248,11 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
}

function renderEditFilter() {
const currentEditFilters = props.multipleFilters.filter(
(filter) => filter.groupId === Number(groupId)
);
let currentEditFilters = [];
groupIds?.forEach((groupId) => {
const filteredFilters = props.multipleFilters.filter(filter => filter.groupId === groupId);
currentEditFilters.push(...filteredFilters);
});

return (
<EuiFlexItem grow={false}>
Expand Down Expand Up @@ -260,11 +285,13 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
groupRef.current?.focus();
}

function onRemoveFilterGroup(gId: string) {
function onRemoveFilterGroup(groupIds: []) {
const multipleFilters = [...props.multipleFilters];

const updatedMultipleFilters = multipleFilters.filter(
(filter) => filter.groupId !== Number(gId)
(filter) => !groupIds.includes(filter.groupId)
);

const filters = [...props.filters];
const updatedFilters: Filter[] = [];

Expand All @@ -282,11 +309,15 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {

function onUpdateFilterGroup(
updatedMultipleFilters: Filter[],
gId: string,
groupIds: [],
toggleNegate = false
) {
const multipleFilters = [...props.multipleFilters];
const notAffectedFilters = multipleFilters.filter((filter) => filter.groupId !== Number(gId));

const notAffectedFilters = multipleFilters.filter(
(filter) => !groupIds.includes(filter.groupId)
);

const finalMultipleFilters = [...notAffectedFilters, ...updatedMultipleFilters];
props?.onMultipleFiltersUpdated?.(finalMultipleFilters);
const filters = [...props.filters];
Expand Down
31 changes: 18 additions & 13 deletions src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ interface Props {
groupedFilters: any;
indexPatterns: IIndexPattern[];
onClick: (filter: Filter) => void;
onRemove: (groupId: string) => void;
onRemove: (filter: Filter[] | unknown[]) => void;
groupId: string;
label?: string | undefined;
filtersGroupsCount: number;
onUpdate?: (filters: Filter[], groupId: string, toggleNegate: boolean) => void;
onEditFilterClick: (groupId: number) => void;
onEditFilterClick: (groupIds: []) => void;
savedQueryService?: SavedQueryService;
onFilterSave?: (savedQueryMeta: SavedQueryMeta, saveAsNew?: boolean) => Promise<void>;
customLabel?: string;
Expand Down Expand Up @@ -81,34 +82,38 @@ export const FilterExpressionItem: FC<Props> = ({
setIsPopoverOpen(!isPopoverOpen);
}

function onEdit(groupId: number) {
onEditFilterClick(groupId);
function onEdit() {
onEditFilterClick([...new Set(groupedFilters.map((filter) => filter.groupId))]);
}

function onDuplicate() {
const lastElement = groupedFilters[groupedFilters.length - 1];
let lastGroupId = lastElement.groupId;
let lastId = lastElement.id;
const multipleUpdatedFilters = groupedFilters?.map((filter: Filter) => {
return { ...filter, groupId: filtersGroupsCount + 1 };
lastId = lastId + 1;
return { ...filter, groupId: lastGroupId + 1, id: lastId };
});
const finalFilters = [...multipleUpdatedFilters, ...groupedFilters];
onUpdate?.(finalFilters, groupId, false);
const finalFilters = [...groupedFilters, ...multipleUpdatedFilters];
onUpdate?.(finalFilters, [...new Set(groupedFilters.map((filter) => filter.groupId))], false);
}

function onToggleNegated() {
const isNegated = groupedFilters[0].groupNegated;
const multipleUpdatedFilters = groupedFilters?.map((filter: Filter) => {
if (filter.meta.negate) {
return { ...filter, meta: { ...filter.meta, negate: false } }
return { ...filter, meta: { ...filter.meta, negate: false } };
} else {
return { ...filter, groupNegated: !isNegated };
}
});

onUpdate?.(multipleUpdatedFilters, groupId, true);
onUpdate?.(multipleUpdatedFilters, [...new Set(groupedFilters.map((filter) => filter.groupId))], true);
}

function onToggleDisabled() {
const multipleUpdatedFilters = groupedFilters?.map(toggleFilterDisabled);
onUpdate?.(multipleUpdatedFilters, groupId, true);
onUpdate?.(multipleUpdatedFilters, [...new Set(groupedFilters.map((filter) => filter.groupId))], true);
}

function getPanels() {
Expand All @@ -120,7 +125,7 @@ export const FilterExpressionItem: FC<Props> = ({
icon: 'pencil',
onClick: () => {
setIsPopoverOpen(false);
onEdit(groupId);
onEdit();
},
'data-test-subj': 'editFilter',
},
Expand Down Expand Up @@ -168,7 +173,7 @@ export const FilterExpressionItem: FC<Props> = ({
icon: 'trash',
onClick: () => {
setIsPopoverOpen(false);
onRemove(groupId);
onRemove([...new Set(groupedFilters.map((filter) => filter.groupId))]);
},
'data-test-subj': 'deleteFilter',
},
Expand Down Expand Up @@ -441,7 +446,7 @@ export const FilterExpressionItem: FC<Props> = ({
? 'globalFilterExpression-isDisabled'
: ''
}
iconOnClick={() => onRemove(groupId)}
iconOnClick={() => onRemove([...new Set(groupedFilters.map((filter) => filter.groupId))])}
iconOnClickAriaLabel={i18n.translate('data.filter.filterBar.filteradgeIconAriaLabel', {
defaultMessage: 'Remove {title}',
values: { title: filterText },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
.kbnQueryBar__filterModalWrapper {
@media only screen and (min-width: map-get($euiBreakpoints, 'm')) {
& {
width: 800px;
width: 994px;
}
}

Expand Down
20 changes: 13 additions & 7 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 @@ -24,13 +24,11 @@ import {
EuiTabs,
EuiTab,
EuiPanel,
EuiSpacer,
EuiHorizontalRule,
EuiButtonIcon,
EuiText,
EuiIcon,
EuiFieldText,
EuiBadge,
} from '@elastic/eui';
import { XJsonLang } from '@kbn/monaco';
import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -79,6 +77,7 @@ export interface FilterGroup {
id: number;
relationship?: string;
subGroupId?: number;
groupsCount?: number;
}

export function AddFilterModal({
Expand All @@ -96,7 +95,11 @@ export function AddFilterModal({
savedQueryService,
}: {
onSubmit: (filters: Filter[]) => void;
onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void;
onMultipleFiltersSubmit: (
filters: FilterGroup[],
buildFilters: Filter[],
groupsCount: number
) => void;
applySavedQueries: () => void;
onCancel: () => void;
filter: Filter;
Expand Down Expand Up @@ -138,6 +141,7 @@ export function AddFilterModal({
: 0,
subGroupId: 1,
relationship: undefined,
groupsCount,
},
]);

Expand Down Expand Up @@ -178,6 +182,7 @@ export function AddFilterModal({
) + 1
: 0,
subGroupId: 1,
groupsCount,
},
]);
setGroupsCount(1);
Expand Down Expand Up @@ -403,7 +408,6 @@ 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;
Expand Down Expand Up @@ -452,7 +456,7 @@ export function AddFilterModal({
) as Filter[];
// onSubmit(finalFilters);

onMultipleFiltersSubmit(localFilters, finalFilters);
onMultipleFiltersSubmit(localFilters, finalFilters, groupsCount);
if (alias) {
saveFilters({
title: customLabel,
Expand Down Expand Up @@ -542,6 +546,7 @@ export function AddFilterModal({
groupId: localfilter.groupId,
id: Number(multipleFilters?.length) + localFilters.length,
subGroupId,
groupsCount,
},
]);
}}
Expand Down Expand Up @@ -584,6 +589,7 @@ export function AddFilterModal({
? localFilters[localFilters.length - 1].groupId
: localFilters[localFilters.length - 1].groupId + 1,
subGroupId,
groupsCount,
id: Number(multipleFilters?.length) + localFilters.length,
},
]);
Expand Down Expand Up @@ -685,7 +691,7 @@ export function AddFilterModal({
};

return (
<EuiModal maxWidth={800} onClose={onCancel} className="kbnQueryBar--addFilterModal">
<EuiModal style={{ minWidth: 992 }} maxWidth={992} onClose={onCancel} className="kbnQueryBar--addFilterModal">
<EuiModalHeader>
<EuiModalHeaderTitle>
<h3>
Expand Down Expand Up @@ -726,7 +732,7 @@ export function AddFilterModal({
<EuiFlexItem>
<EuiFormRow
label={i18n.translate('data.filter.filterEditor.createCustomLabelInputLabel', {
defaultMessage: 'Label (optional)',
defaultMessage: 'Save as (optional)',
})}
display="columnCompressed"
error={i18n.translate('data.search.searchBar.savedQueryForm.titleConflictText', {
Expand Down
Loading

0 comments on commit 820d162

Please sign in to comment.