Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 1 addition & 6 deletions frontend/proxy.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"secure": false,
"changeOrigin": true
},
"/api/models": {
"/api/models": {
"target": "http://localhost:9096",
"secure": false,
"changeOrigin": true
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <img>
// 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", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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 <img> can load.
if (entity.type === EntityType.Workflow) {
return entity.coverImageUrl ?? this.defaultBackground;
}
return this.coverImageUrls.get(this.cacheKey(entity)) || this.defaultBackground;
}
}
Loading