diff --git a/frontend/proxy.config.json b/frontend/proxy.config.json
index 7801e0c256f..47988f6b46e 100755
--- a/frontend/proxy.config.json
+++ b/frontend/proxy.config.json
@@ -15,7 +15,7 @@
"secure": false,
"changeOrigin": true
},
-"/api/models": {
+ "/api/models": {
"target": "http://localhost:9096",
"secure": false,
"changeOrigin": true
@@ -45,11 +45,6 @@
"secure": false,
"changeOrigin": true
},
- "/api/model/**": {
- "target": "http://localhost:9092",
- "secure": false,
- "changeOrigin": true
- },
"/api/access/model/**": {
"target": "http://localhost:9092",
"secure": false,
diff --git a/frontend/src/app/hub/component/browse-section/browse-section.component.spec.ts b/frontend/src/app/hub/component/browse-section/browse-section.component.spec.ts
index 8531fb5247e..b85bb72b982 100644
--- a/frontend/src/app/hub/component/browse-section/browse-section.component.spec.ts
+++ b/frontend/src/app/hub/component/browse-section/browse-section.component.spec.ts
@@ -181,7 +181,40 @@ describe("BrowseSectionComponent", () => {
expect(() => component.ngOnInit()).not.toThrow();
expect(coverCache(component).has("workflow:10")).toBe(false);
expect(coverCache(component).has("computing-unit:12")).toBe(false);
- expect(component.getCoverImage(workflow)).toBe(component.defaultBackground);
+ // Nothing is cached for a workflow, but its cover is readable straight off the entry.
+ expect(component.getCoverImage(workflow)).toBe("carried-on-the-entry");
+ expect(component.getCoverImage(unregistered)).toBe(component.defaultBackground);
+ });
+
+ it("renders a workflow's cover from the entry, since no cover is ever fetched for one", () => {
+ const withCover = {
+ id: 20,
+ type: "workflow",
+ coverImageUrl: "data:image/png;base64,AAAA",
+ accessibleUserIds: [],
+ } as unknown as DashboardEntry;
+ const withoutCover = { id: 21, type: "workflow", accessibleUserIds: [] } as unknown as DashboardEntry;
+ component.entities = [withCover, withoutCover];
+ component.ngOnInit();
+
+ expect(component.getCoverImage(withCover)).toBe("data:image/png;base64,AAAA");
+ expect(component.getCoverImage(withoutCover)).toBe(component.defaultBackground);
+ });
+
+ it("keeps a file-backed kind on the placeholder rather than rendering its stored cover path", () => {
+ // A dataset's coverImageUrl is a path relative to the dataset root, not something an
+ // can load, so it must never stand in for the presigned URL the descriptor resolves.
+ vi.spyOn(TestBed.inject(DatasetService) as any, "getDatasetCoverUrl").mockReturnValue(of({ url: "" }));
+ const entity = {
+ id: 22,
+ type: "dataset",
+ coverImageUrl: "v1/images/preview.png",
+ accessibleUserIds: [],
+ } as unknown as DashboardEntry;
+ component.entities = [entity];
+ component.ngOnInit();
+
+ expect(component.getCoverImage(entity)).toBe(component.defaultBackground);
});
it("caches nothing when the descriptor resolves an empty cover url", () => {
diff --git a/frontend/src/app/hub/component/browse-section/browse-section.component.ts b/frontend/src/app/hub/component/browse-section/browse-section.component.ts
index 65f2075b21c..7d1773e50fa 100644
--- a/frontend/src/app/hub/component/browse-section/browse-section.component.ts
+++ b/frontend/src/app/hub/component/browse-section/browse-section.component.ts
@@ -19,6 +19,7 @@
import { ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges } from "@angular/core";
import { DashboardEntry } from "../../../dashboard/type/dashboard-entry";
+import { EntityType } from "../../service/hub.service";
import { ResourceRegistryService } from "../../../dashboard/service/user/resource-registry/resource-registry.service";
import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy";
import { NgIf, NgFor, NgStyle, DatePipe } from "@angular/common";
@@ -120,6 +121,12 @@ export class BrowseSectionComponent implements OnInit, OnChanges {
}
getCoverImage(entity: DashboardEntry): string {
+ // A workflow's cover is a downscaled data URL carried on the entry, so nothing is ever fetched
+ // for it. The file-backed kinds carry a stored path instead, which only the cache above can
+ // turn into something an
can load.
+ if (entity.type === EntityType.Workflow) {
+ return entity.coverImageUrl ?? this.defaultBackground;
+ }
return this.coverImageUrls.get(this.cacheKey(entity)) || this.defaultBackground;
}
}