This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/main by this push:
new 63db8e3f43 chore(frontend): remove dead search-results inputs and
styles (#8661)
63db8e3f43 is described below
commit 63db8e3f43cdbbc5c031321727bbf937fbbdc6ea
Author: Xinyuan Lin <[email protected]>
AuthorDate: Sun Sep 27 22:08:55 2026 +0000
chore(frontend): remove dead search-results inputs and styles (#8661)
### What changes were proposed in this PR?
Removes the three `SearchResultsComponent` inputs that it never reads
(`searchKeywords`, `showResourceTypes`, `pid`), the parent code that
still computes and binds them, and the CSS in
`search-results.component.scss` and `section-style.scss` that matches no
element it can reach. Pure deletion, no behaviour change: **−172 / +10
lines**.
### History
| | |
| --- | --- |
| **Reads removed by** | #2793 (2024-08-20) — "Generalize List Item"
replaced the per-type list items, and the `nz-layout` / `nz-sider`
resource-type icon around each one, with the generic
`ListItemComponent`, deleting every template read of the three inputs |
| **Never matched** | #2776 (2024-08-19) — `.section-title
.management-panel` and `.section-title .go-back-button` arrived with the
extraction of `section-style.scss` and never matched a template that
includes it |
> Reviewer note — the keyword chain. `searchKeywords` fed each old list
item's `[keywords]` input, which drove the search-term highlight.
`SearchComponent` and `HubSearchResultComponent` kept recomputing it
from the filter bar on every search and binding it into the results
list, where nothing read it. The field and its assignments go in both
parents. The two `SearchComponent` tests that only pinned the field go
too. The tests that asserted on it alongside something still live now
assert on that: the `?q=` tests check the filter bar's master list, the
hub early-return test checks `getSearchFilterParameters`, and the hub
binding test checks `currentUid` alone.
`FiltersComponent.getSearchKeywords()` stays, because the search
requests still call it.
> Reviewer note — `detectChanges()` stays.
`SearchComponent.ngAfterViewInit` assigned the keywords and then called
`this.cdr.detectChanges()`. Only the assignment goes. The call also
re-renders after a `?q=` param is pushed into the filter bar, so it is
not part of the dead chain.
> Reviewer note — the CSS. Component styles use Emulated encapsulation,
so a rule in `search-results.component.scss` can only match that
component's own template: a card, a virtual-scroll list of
`texera-list-item`s, and two text-only "Load more" buttons. `nz-sider`,
`nz-content` and `.resource-type-icon` styled the wrapper #2793 removed.
`.dataset-search-bar`, the `.dataset-list-item { … }` block,
`.subsection-grid-container` and `.ant-btn-icon-only` match nothing
there. The last two also duplicate the identical rules in
`section-style.scss`, which the stylesheet already `@use`s. In
`section-style.scss`, none of the nine stylesheets that include it
belongs to a template containing `management-panel` or `go-back-button`.
The search page's back button is in `SearchComponent`, whose stylesheet
does not include `section-style.scss`, and the hub detail page styles
its own. The commented-out `.utility-button-group` rule goes too. The
header comment that called the layout "shared between workflows and
files section" now says it is shared by the user dashboard's resource
sections.
### Any related issues, documentation, discussions?
Closes #8660
### How was this PR tested?
Existing tests, updated where they asserted on the removed field or
inputs.
From `frontend/`:
- `npx ng build` — **success**. This is the gate that matters: a
leftover `[searchKeywords]` or `[showResourceTypes]` binding on
`texera-search-results` fails only under AOT, since template diagnostics
are AOT-only.
- `npx ng test --watch=false --include='**/search.component.spec.ts'
--include='**/hub-search-result.component.spec.ts'
--include='**/search-results.component.spec.ts'` — 81 tests pass (3
files).
- `yarn format:ci` — clean.
Verification, re-runnable by a reviewer (both return nothing):
```
git grep -n "searchKeywords\|showResourceTypes" -- frontend/src
git grep -n
"resource-type-icon\|dataset-search-bar\|dataset-list-item\|management-panel"
-- frontend/src
```
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Claude Opus 5.5)
---
.../src/app/dashboard/component/section-style.scss | 18 +---
.../search-results/search-results.component.scss | 98 ----------------------
.../search-results/search-results.component.ts | 3 -
.../component/user/search/search.component.html | 6 +-
.../component/user/search/search.component.spec.ts | 27 ++----
.../component/user/search/search.component.ts | 6 --
.../hub-search-result.component.html | 2 -
.../hub-search-result.component.spec.ts | 20 +----
.../hub-search-result.component.ts | 2 -
9 files changed, 10 insertions(+), 172 deletions(-)
diff --git a/frontend/src/app/dashboard/component/section-style.scss
b/frontend/src/app/dashboard/component/section-style.scss
index 446187f502..5dc9167136 100644
--- a/frontend/src/app/dashboard/component/section-style.scss
+++ b/frontend/src/app/dashboard/component/section-style.scss
@@ -40,7 +40,7 @@
* The second row contains the search bar.
* The third row contains the saved workflow/files list.
*
- * This layout is shared between workflows and files section.
+ * This layout is shared by the user dashboard's resource sections.
*
* ******************
* * *
@@ -74,22 +74,6 @@ $dashboard-navigation-height: 76px;
.page-title {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
-
- .management-panel {
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
-
- // .utility-button-group {
- // float: left;
- // }
-
- .go-back-button {
- position: absolute;
- left: 20px;
- top: 20px;
- }
}
/**
diff --git
a/frontend/src/app/dashboard/component/user/search-results/search-results.component.scss
b/frontend/src/app/dashboard/component/user/search-results/search-results.component.scss
index a2c66114a9..c3be0b6f4e 100644
---
a/frontend/src/app/dashboard/component/user/search-results/search-results.component.scss
+++
b/frontend/src/app/dashboard/component/user/search-results/search-results.component.scss
@@ -27,104 +27,6 @@
line-height: 32px;
}
-nz-sider {
- background: rgb(255, 255, 255);
-}
-
-nz-content {
- background: rgb(255, 255, 255);
-}
-
-.resource-type-icon {
- font-size: 30px;
- margin-top: 10px;
- margin-left: 5px;
-}
-
-.dataset-search-bar {
- margin-left: 10px;
-}
-
-.dataset-list-item {
- margin-bottom: 10px;
- min-height: 70px;
- padding: 5px 0 5px 0;
-
- .dataset-item-checkbox {
- margin: 8px;
- }
-
- .dataset-item-meta-title {
- display: flex;
- align-items: center;
-
- .dataset-name {
- font-size: 20px;
- font-family: -apple-system, BlinkMacSystemFont, sans-serif;
- text-align: center;
- margin-bottom: 0;
- color: inherit;
- text-decoration: none;
- }
-
- .dataset-name:hover {
- cursor: pointer;
- }
-
- i {
- position: relative;
- font-size: 17px;
- }
-
- i.dataset-is-owner-icon {
- margin-left: 7px;
- }
- }
-
- .dataset-item-meta-description {
- display: flex;
- align-items: center;
- padding: 2px 8px 2px 10px;
- margin-bottom: 5px;
-
- .dataset-description {
- font-size: 13px;
- font-family: -apple-system, BlinkMacSystemFont, sans-serif;
-
- display: inline-block;
- min-width: 17ch;
- border: 0 none;
- outline: none;
-
- &:hover {
- cursor: pointer;
- box-shadow: 0 0 0 1px rgb(202, 202, 202);
- }
- }
-
- .dataset-editable-description {
- margin-bottom: 5px;
- display: inline-block;
- min-width: 17ch;
- border: 0 none;
- outline: none;
- box-shadow: 0 0 0 2px #007bff;
- }
- }
-}
-
-.subsection-grid-container {
- min-width: 100%;
- width: 100%;
- min-height: 100%;
- height: 100%;
-}
-
-.ant-btn-icon-only {
- margin-left: 5px;
- margin-right: 5px;
-}
-
.card-scroll-container {
height: 100%;
overflow-y: auto;
diff --git
a/frontend/src/app/dashboard/component/user/search-results/search-results.component.ts
b/frontend/src/app/dashboard/component/user/search-results/search-results.component.ts
index baddea9f68..4e122aa4fd 100644
---
a/frontend/src/app/dashboard/component/user/search-results/search-results.component.ts
+++
b/frontend/src/app/dashboard/component/user/search-results/search-results.component.ts
@@ -59,10 +59,7 @@ export class SearchResultsComponent {
entries: ReadonlyArray<DashboardEntry> = [];
private resetCounter = 0;
@Input() isPrivateSearch = false;
- @Input() showResourceTypes = false;
- @Input() public pid: number = 0;
@Input() editable = false;
- @Input() searchKeywords: string[] = [];
@Input() currentUid: number | undefined;
@Input() viewMode: SearchResultsViewMode = "list";
/** Template rendered for each entry in card mode; receives the entry via
$implicit. */
diff --git
a/frontend/src/app/dashboard/component/user/search/search.component.html
b/frontend/src/app/dashboard/component/user/search/search.component.html
index 167b3fcd93..c91a029691 100644
--- a/frontend/src/app/dashboard/component/user/search/search.component.html
+++ b/frontend/src/app/dashboard/component/user/search/search.component.html
@@ -85,10 +85,6 @@
</div>
<div class="search-result">
- <texera-search-results
- [showResourceTypes]="true"
- [searchKeywords]="searchKeywords"
- [currentUid]="this.currentUid">
- </texera-search-results>
+ <texera-search-results
[currentUid]="this.currentUid"></texera-search-results>
</div>
</div>
diff --git
a/frontend/src/app/dashboard/component/user/search/search.component.spec.ts
b/frontend/src/app/dashboard/component/user/search/search.component.spec.ts
index 6a5b244f24..876928f212 100644
--- a/frontend/src/app/dashboard/component/user/search/search.component.spec.ts
+++ b/frontend/src/app/dashboard/component/user/search/search.component.spec.ts
@@ -49,8 +49,7 @@ import { EntityType } from
"../../../../hub/service/hub.service";
// Lightweight stand-in for FiltersComponent. It registers itself under the
real
// FiltersComponent token so SearchComponent's `@ViewChild(FiltersComponent)`
// resolves to it, without dragging in FiltersComponent's six service
-// dependencies and backend-touching ngOnInit. `getSearchKeywords()` mirrors
the
-// current filter list so route-driven searches can be asserted end to end.
+// dependencies and backend-touching ngOnInit.
@Component({
selector: "texera-filters",
template: "",
@@ -61,7 +60,6 @@ class MockFiltersComponent {
@Input() ownerScope?: string;
masterFilterListChange = EMPTY;
masterFilterList: ReadonlyArray<string> = [];
- getSearchKeywords = (): string[] => [...this.masterFilterList];
getSearchFilterParameters = () => ({});
clearFacetSelections = vi.fn();
}
@@ -71,8 +69,6 @@ class MockFiltersComponent {
template: "",
})
class MockSearchResultsComponent {
- @Input() showResourceTypes = false;
- @Input() searchKeywords: string[] = [];
@Input() currentUid?: number;
}
@@ -141,10 +137,6 @@ describe("SearchComponent", () => {
expect(() => fixture.detectChanges()).not.toThrow();
});
- it("starts with an empty searchKeywords list so the template binding is
always safe", () => {
- expect(component.searchKeywords).toEqual([]);
- });
-
// ─── filters getter / setter
────────────────────────────────────────────────
it("throws from the filters getter before the ViewChild has resolved", () =>
{
@@ -169,33 +161,24 @@ describe("SearchComponent", () => {
// ─── ngAfterViewInit / query params
─────────────────────────────────────────
- it("applies the `q` query param to the filters and populates
searchKeywords", () => {
+ it("applies the `q` query param to the filters", () => {
fixture.detectChanges(); // resolves the filters ViewChild and subscribes
to queryParams
queryParams$.next({ q: "foo bar" });
expect(component.searchParam).toBe("foo bar");
- expect(component.searchKeywords).toEqual(["foo", "bar"]);
+ expect(component.filters.masterFilterList).toEqual(["foo", "bar"]);
});
- it("leaves searchParam empty and searchKeywords empty when there is no `q`
param", () => {
+ it("leaves searchParam and the filters empty when there is no `q` param", ()
=> {
fixture.detectChanges();
queryParams$.next({});
expect(component.searchParam).toBe("");
- expect(component.searchKeywords).toEqual([]);
+ expect(component.filters.masterFilterList).toEqual([]);
});
// ─── search()
───────────────────────────────────────────────────────────────
- it("syncs searchKeywords from the filters when a search runs", async () => {
- component.filters = makeFiltersDouble(["alpha", "beta"]);
- component.searchResultsComponent = makeSearchResultsDouble() as unknown as
SearchResultsComponent;
-
- await component.search();
-
- expect(component.searchKeywords).toEqual(["alpha", "beta"]);
- });
-
it("drives the results component (reset + loadMore) on a fresh search",
async () => {
component.filters = makeFiltersDouble(["x"]);
const results = makeSearchResultsDouble();
diff --git
a/frontend/src/app/dashboard/component/user/search/search.component.ts
b/frontend/src/app/dashboard/component/user/search/search.component.ts
index 7ef7d22c90..db27a92c7a 100644
--- a/frontend/src/app/dashboard/component/user/search/search.component.ts
+++ b/frontend/src/app/dashboard/component/user/search/search.component.ts
@@ -62,7 +62,6 @@ export class SearchComponent implements AfterViewInit {
private isLogin = this.userService.isLogin();
private includePublic = true;
currentUid = this.userService.getCurrentUser()?.uid;
- searchKeywords: string[] = [];
selectedType: "workflow" | "dataset" | "model" | null = null;
@@ -112,16 +111,11 @@ export class SearchComponent implements AfterViewInit {
this.updateMasterFilterList();
}
- this.searchKeywords = this.filters.getSearchKeywords();
this.cdr.detectChanges();
});
}
async search(): Promise<void> {
- // Keep the highlight keywords in sync with the current filters. This is
read
- // by the template's search-results binding; the template must not call the
- // `filters` getter directly, since it throws until the ViewChild resolves.
- this.searchKeywords = this.filters.getSearchKeywords();
const sameList =
this.filters.masterFilterList.length === this.masterFilterList.length &&
this.filters.masterFilterList.every((v, i) => v ===
this.masterFilterList[i]);
diff --git
a/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.html
b/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.html
index 18604d4273..9e5c03dd89 100644
---
a/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.html
+++
b/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.html
@@ -66,8 +66,6 @@
<div class="search-result">
<texera-search-results
- [showResourceTypes]="true"
- [searchKeywords]="searchKeywords"
[currentUid]="this.currentUid"
[viewMode]="isVersionedResource ? viewMode : 'list'"
[cardTemplate]="isVersionedResource ? cardTpl : undefined">
diff --git
a/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.spec.ts
b/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.spec.ts
index 56df200a84..fd16d9d54d 100644
---
a/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.spec.ts
+++
b/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.spec.ts
@@ -80,7 +80,6 @@ class StubFiltersComponent {
@Input() ownerScope?: string;
masterFilterList: ReadonlyArray<string> = [];
masterFilterListChange = new Subject<ReadonlyArray<string>>();
- getSearchKeywords = vi.fn(() => [] as string[]);
getSearchFilterParameters = vi.fn(() => ({}));
}
@@ -90,8 +89,6 @@ class StubFiltersComponent {
template: "",
})
class StubSearchResultsComponent {
- @Input() showResourceTypes?: boolean;
- @Input() searchKeywords?: string[];
@Input() currentUid?: number;
@Input() viewMode?: string;
@Input() cardTemplate?: TemplateRef<unknown>;
@@ -109,7 +106,6 @@ class StubCardItemComponent {
interface FiltersMock {
masterFilterList: ReadonlyArray<string>;
- getSearchKeywords: ReturnType<typeof vi.fn>;
getSearchFilterParameters: ReturnType<typeof vi.fn>;
masterFilterListChange: Subject<ReadonlyArray<string>>;
}
@@ -164,7 +160,6 @@ describe("HubSearchResultComponent", () => {
function makeFiltersMock(list: ReadonlyArray<string> = ["a"]): FiltersMock {
return {
masterFilterList: list,
- getSearchKeywords: vi.fn(() => ["k"]),
getSearchFilterParameters: vi.fn(() => ({})),
masterFilterListChange: new Subject<ReadonlyArray<string>>(),
};
@@ -308,7 +303,7 @@ describe("HubSearchResultComponent", () => {
await component.search();
- expect(filters.getSearchKeywords).not.toHaveBeenCalled();
+ expect(filters.getSearchFilterParameters).not.toHaveBeenCalled();
expect(searchServiceMock.executeSearch).not.toHaveBeenCalled();
});
@@ -323,7 +318,6 @@ describe("HubSearchResultComponent", () => {
expect(results.reset).toHaveBeenCalledTimes(1);
expect(typeof results.reset.mock.calls[0][0]).toBe("function");
expect(results.loadMore).toHaveBeenCalledTimes(1);
- expect(component.searchKeywords).toEqual(["k"]);
});
it("skips a repeated search with the same filter list and sortMethod, but
honors forced=true", async () => {
@@ -637,19 +631,11 @@ describe("HubSearchResultComponent rendered template", ()
=> {
expect(results().cardTemplate).toBeUndefined();
});
- it("hands the resource types, the filter keywords and the signed-in uid to
the results list", () => {
+ it("hands the signed-in uid to the results list", () => {
render(EntityType.Workflow);
- const filters =
fixture.debugElement.query(By.directive(FiltersComponent)).componentInstance as
FiltersComponent;
- // Committing a filter list is what the real filter bar does on every
change, and it
- // is what makes the component republish its keywords.
- filters.masterFilterList = ["alpha"];
- fixture.detectChanges();
-
- // Asserted on the child inputs rather than the DOM because all three only
reach the
+ // Asserted on the child input rather than the DOM because currentUid only
reaches the
// markup through texera-list-item, which is not rendered while the result
list is empty.
- expect(results().showResourceTypes).toBe(true);
- expect(results().searchKeywords).toEqual(["alpha"]);
expect(results().currentUid).toBe(MOCK_USER_ID);
});
});
diff --git
a/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.ts
b/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.ts
index cfe9c59e3a..e2608a6fbe 100644
---
a/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.ts
+++
b/frontend/src/app/hub/component/hub-search-result/hub-search-result.component.ts
@@ -74,7 +74,6 @@ export class HubSearchResultComponent implements OnInit,
AfterViewInit {
return this.entityType === EntityType.Dataset || this.entityType ===
EntityType.Model;
}
- public searchKeywords: string[] = [];
currentUid = this.userService.getCurrentUser()?.uid;
public viewMode: SearchResultsViewMode =
localStorage.getItem(HUB_VIEW_MODE_STORAGE_KEY) === "card" ? "card" : "list";
@@ -155,7 +154,6 @@ export class HubSearchResultComponent implements OnInit,
AfterViewInit {
}
this.lastSortMethod = this.sortMethod;
this.masterFilterList = this.filters.masterFilterList;
- this.searchKeywords = this.filters.getSearchKeywords();
let filterParams = this.filters.getSearchFilterParameters();
this.searchResultsComponent.reset((start, count) => {