Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
5 changes: 5 additions & 0 deletions .changeset/giant-poets-fall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@esri/hub-common": patch
---

Items of type "Image" will now display their data as the default image in workspaces
92 changes: 2 additions & 90 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions packages/common/src/content/_internal/ContentUiSchemaEdit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { getTagItems } from "../../core/schemas/internal/getTagItems";
import { getLocationExtent } from "../../core/schemas/internal/getLocationExtent";
import { getLocationOptions } from "../../core/schemas/internal/getLocationOptions";
import { IUiSchema } from "../../core/schemas/types";
import { getThumbnailUiSchemaElement } from "../../core/schemas/internal/getThumbnailUiSchemaElement";
import {
getDefaultImageEntityThumbnail,
getThumbnailUiSchemaElement,
} from "../../core/schemas/internal/getThumbnailUiSchemaElement";
import { IHubEditableContent } from "../../core/types/IHubEditableContent";
import { fetchCategoriesUiSchemaElement } from "../../core/schemas/internal/fetchCategoriesUiSchemaElement";
// import { getSlugSchemaElement } from "../../core/schemas/internal/getSlugSchemaElement";

/**
* @private
Expand Down Expand Up @@ -81,7 +83,8 @@ export const buildUiSchema = async (
options.thumbnail,
options.thumbnailUrl,
"content",
context.requestOptions
context.requestOptions,
getDefaultImageEntityThumbnail(options, context)
),
{
type: "Section",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { IRequestOptions } from "@esri/arcgis-rest-request";
import { getCdnAssetUrl } from "../../../urls/get-cdn-asset-url";
import { HubEntityType } from "../../types/HubEntityType";
import { IUiSchemaElement } from "../types";
import { getItemDataUrl } from "../../../urls/get-item-data-url";
import { IItem } from "@esri/arcgis-rest-portal";
import { IHubEditableContent } from "../../types/IHubEditableContent";
import { IArcGISContext } from "../../../types/IArcGISContext";

const DEFAULT_ENTITY_THUMBNAILS: Partial<Record<HubEntityType, string>> = {
discussion:
Expand All @@ -14,24 +18,55 @@ const DEFAULT_ENTITY_THUMBNAILS: Partial<Record<HubEntityType, string>> = {
"/ember-arcgis-opendata-components/assets/images/placeholders/content.png",
};

/**
* To only be used by IHubEditableContent entities when attempting to determine
* the default thumbnail for a content entity with a type of "Image"
*
* For test coverage purposes, I've move this logic out of the buildUiSchema function.
*
* @param options
* @param context
* @returns string | undefined
*/
export const getDefaultImageEntityThumbnail = (
options: Partial<IHubEditableContent>,
context: IArcGISContext
): string | undefined => {
return options.type === "Image"
? // if the content is an Image, use its own data url as the default thumbnail
getItemDataUrl(
{ id: options.id, access: options.access } as IItem,
context.hubRequestOptions,
context.hubRequestOptions.authentication?.token
)
: undefined;
};

/**
* Returns the UI schema element needed to render
* the thumbnail editing control for an item-based entity.
*
* @param i18nScope i18n scope for the entity translations
* @param entity The entity to build the UI schema for
* @param thumbnail current thumbnail filename
* @param thumbnailUrl current thumbnail URL
* @param entityType the type of entity (content, group, event, etc)
* @param requestOptions request options
* @param defaultThumbnailUrl optional default thumbnail url to use instead of the standard one
* @returns the UI schema element for thumbnail editing
*/
export function getThumbnailUiSchemaElement(
i18nScope: string,
thumbnail: string,
thumbnailUrl: string,
entityType: HubEntityType,
requestOptions: IRequestOptions
requestOptions: IRequestOptions,
defaultThumbnailUrl?: string
): IUiSchemaElement[] {
const defaultEntityThumbnail =
DEFAULT_ENTITY_THUMBNAILS[entityType] ?? DEFAULT_ENTITY_THUMBNAILS.content;
const defaultImgUrl = getCdnAssetUrl(defaultEntityThumbnail, requestOptions);
const defaultImgUrl =
defaultThumbnailUrl ||
getCdnAssetUrl(defaultEntityThumbnail, requestOptions);

let options;
if (entityType === "group") {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {
describe,
it,
expect,
vi,
} from "vitest";
import { describe, it, expect, vi } from "vitest";
import { IRequestOptions } from "@esri/arcgis-rest-request";
import { IHubItemEntity } from "../../../../src/core/types/IHubItemEntity";
import { getThumbnailUiSchemaElement } from "../../../../src/core/schemas/internal/getThumbnailUiSchemaElement";
import {
getDefaultImageEntityThumbnail,
getThumbnailUiSchemaElement,
} from "../../../../src/core/schemas/internal/getThumbnailUiSchemaElement";
import { HubEntityType } from "../../../../src/core/types/HubEntityType";
import * as getCdnAssetUrlModule from "../../../../src/urls/get-cdn-asset-url";
import { IItem } from "@esri/arcgis-rest-portal";
import * as getItemDataUrlModule from "../../../../src/urls/get-item-data-url";

describe("getThumbnailUiSchemaElement:", () => {
it("returns schema when the entity has a thumbnail", () => {
Expand Down Expand Up @@ -127,3 +127,29 @@ describe("getThumbnailUiSchemaElement:", () => {
expect(uiSchema[0].options?.defaultImgUrl).toBe(defaultImageUrl);
});
});

describe("getDefaultImageEntityThumbnail:", () => {
it("returns undefined for non-Image content", () => {
const result = getDefaultImageEntityThumbnail(
{ type: "Web Map" } as any,
{} as any
);
expect(result).toBeUndefined();
});

it("returns data url for Image content", async () => {
const getItemDataUrlSpy = vi
.spyOn(getItemDataUrlModule, "getItemDataUrl")
.mockResolvedValue("the data url");
const result = await getDefaultImageEntityThumbnail(
{ id: "abc", access: "private", type: "Image" },
{ hubRequestOptions: {} } as any
);
expect(getItemDataUrlSpy).toHaveBeenCalledWith(
{ id: "abc", access: "private" } as IItem,
{},
undefined
);
expect(result).toBe("the data url");
});
});