Skip to content

Commit

Permalink
Fix date field distinct values for filters section (#1767)
Browse files Browse the repository at this point in the history
  • Loading branch information
kuzmadom authored Oct 31, 2024
1 parent 5d8384c commit 52191d2
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 58 deletions.
26 changes: 13 additions & 13 deletions src/ui/components/DialogFilter/DialogFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,19 @@ class DialogFilter extends React.Component<DialogFilterProps, DialogFilterState>
return null;
}

if (operation.selectable && !useManualInput) {
return (
<SelectFilter
values={values}
dimensions={dimensions}
useSuggest={useSuggest}
suggestFetching={suggestFetching}
changeValue={this.onChangeValue}
onChangeSuggest={this.debouncedChangeSuggest}
/>
);
}

const commonDataType = getCommonDataType(this.field);

switch (commonDataType) {
Expand All @@ -361,19 +374,6 @@ class DialogFilter extends React.Component<DialogFilterProps, DialogFilterState>
}

default: {
if (operation.selectable && !useManualInput) {
return (
<SelectFilter
values={values}
dimensions={dimensions}
useSuggest={useSuggest}
suggestFetching={suggestFetching}
changeValue={this.onChangeValue}
onChangeSuggest={this.debouncedChangeSuggest}
/>
);
}

return (
<InputFilter
values={values as string[]}
Expand Down
1 change: 1 addition & 0 deletions src/ui/components/DialogFilter/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const DATE_OPERATIONS: Operation[] = [
...BASE_EQUALITY_OPERATIONS.map((item) => ({...item, range: false})),
...BASE_COMPARSION_OPERATIONS.map((item) => ({...item, range: false})),
...BASE_NULL_OPERATIONS.map((item) => ({...item, range: false})),
...BASE_SET_OPERATIONS.map((item) => ({...item, selectable: true})),
];

export const ARRAY_OPERATIONS: Operation[] = [
Expand Down
95 changes: 56 additions & 39 deletions src/ui/units/wizard/utils/wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,20 @@ export function getFiltersFields(
fields: Field[],
): {filtersFields: Field[]; chartFilters: FilterField[]} {
const filtersFields: Field[] = [];
paramsPairs.forEach((paramPair) => {
const groupedParams = paramsPairs.reduce<Record<string, string[]>>((acc, paramPair) => {
const key = paramPair[0];
const urlValue: string = paramPair[1];

if (!(key in acc)) {
acc[key] = [];
}

acc[key].push(urlValue);

return acc;
}, {});

Object.entries(groupedParams).forEach(([key, values]) => {
// Let's try to find the filtered field
const foundItem = findFieldInDatasetSection({
datasetSectionFields: fields,
Expand All @@ -334,49 +344,56 @@ export function getFiltersFields(
}

const isFilterAlreadyInChart = filters.find((filter) => filter.guid === foundItem.guid);
if (!urlValue && isFilterAlreadyInChart && Utils.isEnabledFeature(Feature.EmptySelector)) {
filtersFields.push({
...foundItem,
unsaved: true,
filter: {
operation: {code: Operations.NO_SELECTED_VALUES},
value: [''],
},
});
} else if (urlValue === '') {
return;
}

const defaultOperation = isDateField(foundItem) ? Operations.EQ : undefined;
const parsedFiltersOperation = resolveOperation(urlValue, defaultOperation);
const defaultOperation =
isDateField(foundItem) && values.length === 1 ? Operations.EQ : undefined;

values.forEach((urlValue) => {
if (
!urlValue &&
isFilterAlreadyInChart &&
Utils.isEnabledFeature(Feature.EmptySelector)
) {
filtersFields.push({
...foundItem,
unsaved: true,
filter: {
operation: {code: Operations.NO_SELECTED_VALUES},
value: [''],
},
});
} else if (urlValue === '') {
return;
}

if (!parsedFiltersOperation) {
return;
}
const parsedFiltersOperation = resolveOperation(urlValue, defaultOperation);
if (!parsedFiltersOperation) {
return;
}

const code = parsedFiltersOperation.operation;
const value: string[] = [parsedFiltersOperation.value];
const code = parsedFiltersOperation.operation;
const value: string[] = [parsedFiltersOperation.value];

// Let's try to find such a filter among the parameters created from search
const foundFilter = filtersFields.find((item) => {
return item.guid === key || item.title === key;
});
// Let's try to find such a filter among the parameters created from search
const foundFilter = filtersFields.find((item) => {
return item.guid === key || item.title === key;
});

// If such a filter is found, then we do not create a new one, but supplement the old one, but only if the operator supports multi-selection
if (foundFilter && (code === Operations.IN || code === Operations.NIN)) {
foundFilter.filter!.value = [...foundFilter.filter!.value, ...value];
} else {
filtersFields.push({
...foundItem,
unsaved: true,
filter: {
operation: {
code,
// If such a filter is found, then we do not create a new one, but supplement the old one, but only if the operator supports multi-selection
if (foundFilter && (code === Operations.IN || code === Operations.NIN)) {
foundFilter.filter!.value = [...foundFilter.filter!.value, ...value];
} else {
filtersFields.push({
...foundItem,
unsaved: true,
filter: {
operation: {
code,
},
value,
},
value,
},
});
}
});
}
});
});

const chartFilters = getChartFiltersWithDisabledProp({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import {PlaceholderName} from '../../../page-objects/wizard/SectionVisualization
import WizardPage from '../../../page-objects/wizard/WizardPage';
import datalensTest from '../../../utils/playwright/globalTestDefinition';
import {openTestPage} from '../../../utils';
import {WizardVisualizationId} from '../../../../src/shared';

const chartNamePattern = 'e2e-wizard-filters';

const setupFilters = async (wizardPage: WizardPage) => {
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Filters, 'city');
Expand All @@ -17,22 +20,28 @@ const setupFilters = async (wizardPage: WizardPage) => {

datalensTest.describe('Wizard filters', () => {
datalensTest.beforeEach(async ({page, config}) => {
const wizardPage = new WizardPage({page});

await openTestPage(page, config.wizard.urls.WizardBasicDataset);
});

await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'city');

await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'city');
datalensTest.afterEach(async ({page}) => {
await page.reload();
const pageUrl = page.url();

await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Colors, 'city');
if (pageUrl.includes(chartNamePattern)) {
const wizardPage = new WizardPage({page});
await wizardPage.deleteEntry();
}
});

datalensTest(
'All chart filters must be taken into account in the color dialog',
async ({page}: {page: Page}) => {
const wizardPage = new WizardPage({page});

await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.X, 'city');
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Y, 'city');
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Colors, 'city');

await wizardPage.colorDialog.open();

const valuesWithoutFilters = await wizardPage.colorDialog.getFieldValues();
Expand All @@ -52,4 +61,34 @@ datalensTest.describe('Wizard filters', () => {
expect(valuesWithFilters).toEqual(['Los Angeles']);
},
);

datalensTest(
'Two or more values of the Date field from the dashboard filter section should use IN operation by default',
async ({page}: {page: Page}) => {
const dateFilterValues = ['2015-01-01', '2016-01-01'];
const wizardPage = new WizardPage({page});
await wizardPage.setVisualization(WizardVisualizationId.PieD3);

await wizardPage.createNewFieldWithFormula(
'order_year',
`DATETRUNC([Order_date], 'year')`,
);
await wizardPage.createNewFieldWithFormula('sum', 'sum([Sales])');
await wizardPage.sectionVisualization.addFieldByClick(
PlaceholderName.Colors,
'order_year',
);
await wizardPage.sectionVisualization.addFieldByClick(PlaceholderName.Measures, 'sum');

await wizardPage.saveWizardEntry(wizardPage.getUniqueEntryName(chartNamePattern));

const pageUrl = new URL(page.url());
dateFilterValues.forEach((d) => pageUrl.searchParams.append('order_year', d));
await page.goto(pageUrl.toString());

await wizardPage.colorDialog.open();
await wizardPage.colorDialog.checkFieldValues(dateFilterValues);
await wizardPage.colorDialog.close();
},
);
});
6 changes: 6 additions & 0 deletions tests/page-objects/wizard/ColorDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ export default class ColorDialog {
await this.page.click(this.cancelButtonSelector);
}

async checkFieldValues(text: string[]) {
const items = this.page.locator(this.valueLabelSelector);
await expect(items.first()).toBeVisible();
await expect(items).toHaveText(text);
}

async getFieldValues(): Promise<string[]> {
await this.page.waitForSelector(this.valueLabelSelector);
const elements = await this.page.$$(this.valueLabelSelector);
Expand Down

0 comments on commit 52191d2

Please sign in to comment.