Skip to content

refactor: improve filters and conditions section in dataset dashboard #1927

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

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
21946cd
moved conditions management from settings filter to main filter compo…
abdimo101 Jul 7, 2025
2b41640
Merge branch 'master' of github.com:SciCatProject/frontend
abdimo101 Jul 7, 2025
5206918
small css fix
abdimo101 Jul 7, 2025
af84edd
moved conditions management from settings filter to main filter compo…
abdimo101 Jul 7, 2025
390fa21
small css fix
abdimo101 Jul 7, 2025
4d96e37
eslint fix
abdimo101 Jul 8, 2025
42b9918
Merge branch 'datasets-filter-conditions' of github.com:SciCatProject…
abdimo101 Jul 8, 2025
8f76dcb
solved merge conflict
abdimo101 Jul 8, 2025
ed2add5
added ScientificCondition type and removed 'as any'
abdimo101 Jul 8, 2025
1010a6f
test for pre-configured filters
abdimo101 Jul 11, 2025
523a96b
applied enabled pre-configured conditions on init
abdimo101 Jul 12, 2025
1f1c82c
small change in e2e datasets-general
abdimo101 Jul 14, 2025
56353ec
modified pre-configured conditions e2e test
abdimo101 Jul 14, 2025
cb304cd
eslint fix
abdimo101 Jul 14, 2025
51b6d47
added condition in frontend.config.e2e file, eslint fix
abdimo101 Jul 14, 2025
2ab1e41
small fix in pre-configured tests
abdimo101 Jul 14, 2025
bf953c2
fix eslint and small change in pre-configured conditions test
abdimo101 Jul 14, 2025
97b5f40
WIP: added cypress dataset with overrides and cleanup
abdimo101 Jul 15, 2025
dab59b1
WIP: after all hook uncommented
abdimo101 Jul 15, 2025
62c8f24
small change in filters test
abdimo101 Jul 15, 2025
b983d4f
removed '.only' from describe
abdimo101 Jul 15, 2025
77d8ac2
e2e fix in filters test
abdimo101 Jul 16, 2025
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
181 changes: 168 additions & 13 deletions cypress/e2e/datasets/datasets-general.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ describe("Datasets general", () => {
cy.login(Cypress.env("username"), Cypress.env("password"));
});

after(() => {
cy.removeDatasets();
});
after(() => {
cy.removeDatasets();
});

describe("Show dataset table after logout and login", () => {
it("should be able to see datasets after visiting details page logout and login again", () => {
Expand Down Expand Up @@ -112,16 +112,18 @@ describe("Datasets general", () => {

cy.visit("/datasets");

cy.get('[data-cy="more-filters-button"]').click();

cy.get('[data-cy="add-scientific-condition-button"]').click();
cy.get('[data-cy="scientific-condition-filter-list"]').within(() => {
cy.get('button').contains('Add Conditions').click();
});

cy.get('input[name="lhs"]').type("test");
cy.get('input[name="rhs"]').type("1");

cy.get('button[type="submit"]').click();

cy.get('[data-cy="add-scientific-condition-button"]').click();
cy.get('[data-cy="scientific-condition-filter-list"]').within(() => {
cy.get('button').contains('Add Conditions').click();
});

cy.get('input[name="lhs"]').type("test");
cy.get('input[name="rhs"]').type("1");
Expand All @@ -133,21 +135,174 @@ describe("Datasets general", () => {
.contains("Close")
.click();

cy.get('[data-cy="scientific-condition-filter-list"').should(
"have.length",
1,
);
cy.get('[data-cy="scientific-condition-filter-list"]')
.find('.condition-panel')
.should("have.length", 1);

cy.get('[data-cy="add-scientific-condition-button"]').click();
cy.get('[data-cy="scientific-condition-filter-list"]').within(() => {
cy.get('button').contains('Add Conditions').click();
});

cy.get('input[name="lhs"]').type("test");
cy.get('input[name="rhs"]').type("2");

cy.get('button[type="submit"]').click();

cy.get('[data-cy="scientific-condition-filter-list"]')
.find("input")
.find('.condition-panel')
.should("have.length", 2);
});

it("should be able to manage conditions using expansion panels", () => {
cy.visit("/datasets");

cy.get(".user-button").click();

cy.get("[data-cy=logout-button]").click();

cy.finishedLoading();

cy.visit("/datasets");

cy.get('[data-cy="scientific-condition-filter-list"]').within(() => {
cy.get('button').contains('Add Conditions').click();
});

cy.get('input[name="lhs"]').type("test 3");
cy.get('input[name="rhs"]').type("3");

cy.get('button[type="submit"]').click();

cy.get('.condition-panel').first().click();

cy.get('.condition-details').should('be.visible');

cy.get('.condition-details').within(() => {
cy.get('mat-select').should('exist');
cy.get('input[matInput]').should('exist');
cy.get('mat-slide-toggle').should('exist');
cy.get('button').contains('Remove').should('exist');
});

cy.get('.condition-details').within(() => {
cy.get('mat-slide-toggle').click();
});

cy.get('.condition-panel').should('have.class', 'disabled');

cy.get('.condition-details').within(() => {
cy.get('button').contains('Remove').click();
});

cy.get('[data-cy="scientific-condition-filter-list"]')
.find('.condition-panel')
.should("have.length", 0);
});

});

describe("Pre-configured filters test", () => {
beforeEach(() => {
cy.clearCookies();
cy.clearLocalStorage();
cy.readFile("CI/e2e/frontend.config.e2e.json").then((baseConfig) => {
const testConfig = {
...baseConfig,
defaultDatasetsListSettings: {
...baseConfig.defaultDatasetsListSettings,
filters: [
{ "TypeFilter": true },
{ "TextFilter": true }
]
}
};

cy.intercept("GET", "**/admin/config", testConfig).as("getConfig");
cy.visit("/datasets");
cy.wait("@getConfig", { timeout: 10000 });
cy.finishedLoading();
});
});

it("should automatically apply pre-configured filters from config", () => {
cy.contains("Type").should("exist");

cy.get('[data-cy="text-search"]').should("exist");

cy.contains("Location").should("not.exist");
cy.contains("Keyword").should("not.exist");
});
});

describe("Pre-configured conditions test", () => {
beforeEach(() => {
cy.login(Cypress.env("username"), Cypress.env("password"));
cy.createDataset(
"raw",
testData.rawDataset.datasetName,
undefined,
"small",
{
scientificMetadata: {
extra_entry_end_time: { value: "2", unit: "" },
},
isPublished: true,
},
).then(() => {
cy.clearCookies();
cy.clearLocalStorage();

cy.readFile("CI/e2e/frontend.config.e2e.json").then((baseConfig) => {
const testConfig = {
...baseConfig,
defaultDatasetsListSettings: {
...baseConfig.defaultDatasetsListSettings,
conditions: [
{
condition: {
lhs: "extra_entry_end_time",
relation: "GREATER_THAN",
rhs: 1,
unit: "",
},
enabled: true,
},
],
},
};

cy.intercept("GET", "**/admin/config", testConfig).as("getConfig");
cy.visit("/datasets");
cy.wait("@getConfig");
cy.finishedLoading();
});
});
});

it("should check if pre-configured conditions are applied", () => {
cy.get('[data-cy="scientific-condition-filter-list"] .condition-panel')
.should("contain.text", "extra_entry_end_time")
.and("contain.text", ">")
.and("contain.text", "1");

cy.get(".dataset-table mat-table").should("exist");
cy.get(".dataset-table mat-row").first().click();
cy.get(".metadataTable", { timeout: 10000 }).scrollIntoView();

cy.get(".metadataTable mat-row").within(() => {
cy.get(".mat-column-human_name label")
.invoke("text")
.then((fieldName) => {
if (fieldName && fieldName.trim() === "Extra Entry End Time") {
cy.get(".mat-column-value label")
.invoke("text")
.then((valueText) => {
const value = parseFloat(valueText.trim());
expect(value).to.be.greaterThan(1);
});
}
});
});
});
});
});
3 changes: 2 additions & 1 deletion cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,14 @@ Cypress.Commands.add(
datasetName = testData.rawDataset.datasetName,
proposalId = "20170266",
dataFileSize = "small",
overrides = {}
) => {
cy.getCookie("user").then((userCookie) => {
const user = JSON.parse(decodeURIComponent(userCookie.value));

cy.getToken().then((token) => {
if (type === "raw") {
const dataset = { ...testData.rawDataset, datasetName, proposalId };
const dataset = { ...testData.rawDataset, datasetName, proposalId, ...overrides, };
cy.log("Raw Dataset 1: " + JSON.stringify(dataset, null, 2));
cy.log("User: " + JSON.stringify(user, null, 2));

Expand Down
141 changes: 124 additions & 17 deletions src/app/datasets/datasets-filter/datasets-filter.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
<mat-card>
<mat-card-header class="section-container">
<mat-card-title>Filters and Conditions</mat-card-title>
<mat-card-title>Filters</mat-card-title>
<div class="section-container" data-cy="more-filters-button">
<button
mat-button
class="settings-button"
(click)="showDatasetsFilterSettingsDialog()"
>
<mat-icon>settings</mat-icon>
</button>
</div>
</mat-card-header>

<mat-card-content>
Expand All @@ -16,27 +25,125 @@
</ng-container>
</ng-container>
</ng-container>

<div
class="section-container"
class="section-container scientific-conditions"
*ngIf="appConfig.scienceSearchEnabled"
data-cy="scientific-condition-filter-list"
>
<ng-container *ngFor="let condition of scientificConditions$ | async">
<ng-container
*ngComponentOutlet="ConditionFilterComponent; inputs: { condition }"
></ng-container>
</ng-container>
</div>

<div class="section-container" data-cy="more-filters-button">
<button
mat-button
class="full-width-button"
(click)="showDatasetsFilterSettingsDialog()"
<mat-card-title>Conditions</mat-card-title>
<mat-accordion
multi="true"
*ngIf="conditionConfigs$ | async as conditionConfigs"
>
<mat-icon>tune</mat-icon>More Filters...
</button>
<mat-expansion-panel
*ngFor="
let conditionConfig of conditionConfigs;
let i = index;
trackBy: trackByCondition
"
class="condition-panel"
[class.disabled]="!conditionConfig.enabled"
>
<mat-expansion-panel-header class="custom-panel-header">
<mat-panel-title>
<div class="condition-title-section">
<div class="condition-field-name">
{{ conditionConfig.condition.lhs }}
</div>
<div class="condition-description">
{{ getConditionDisplayText(conditionConfig.condition) }}
</div>
</div>
</mat-panel-title>
<mat-panel-description>
{{ getConditionDisplayText(conditionConfig.condition) }}
</mat-panel-description>
</mat-expansion-panel-header>

<div class="condition-details">
<mat-form-field appearance="outline" class="condition-fields">
<mat-label>Operator</mat-label>
<mat-select
[value]="conditionConfig.condition.relation"
(selectionChange)="updateConditionOperator(i, $event.value)"
>
<mat-option value="GREATER_THAN">is greater than</mat-option>
<mat-option value="LESS_THAN">is less than</mat-option>
<mat-option value="EQUAL_TO_NUMERIC"
>is equal to (numeric)</mat-option
>
<mat-option value="EQUAL_TO_STRING"
>is equal to (string)</mat-option
>
</mat-select>
</mat-form-field>

<mat-form-field appearance="outline" class="condition-fields">
<mat-label>Value</mat-label>
<input
matInput
[value]="conditionConfig.condition.rhs"
(input)="updateConditionValue(i, $event)"
/>
</mat-form-field>

<ng-template [ngIf]="appConfig.scienceSearchUnitsEnabled">
<mat-form-field appearance="outline" class="condition-fields">
<mat-label>Unit</mat-label>
<input
matInput
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
[value]="conditionConfig.condition.unit || ''"
(input)="updateConditionUnit(i, $event)"
[matAutocomplete]="rhsUnits"
[disabled]="
conditionConfig.condition.relation === 'EQUAL_TO_STRING'
"
/>
<mat-autocomplete #rhsUnits="matAutocomplete">
<mat-option
*ngFor="let unit of getUnits(conditionConfig.condition.lhs)"
[value]="unit"
>
{{ unit }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</ng-template>

<div class="condition-actions-section">
<mat-slide-toggle
[checked]="conditionConfig.enabled"
(change)="toggleConditionEnabled(i, $event.checked)"
matTooltip="Enable/Disable condition"
class="condition-toggle"
>
{{ conditionConfig.enabled ? "Enabled" : "Disabled" }}
</mat-slide-toggle>

<button
class="condition-remove"
mat-button
color="warn"
(click)="removeCondition(conditionConfig, i)"
matTooltip="Remove condition"
>
<mat-icon>delete</mat-icon>
Remove
</button>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>

<div class="conditions-header">
<button mat-button class="condition-button" (click)="addCondition()">
<mat-icon>add</mat-icon>Add Conditions
</button>
</div>
</div>

<div class="section-container">
Expand Down
Loading
Loading