Skip to content
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

feat(hub-common): append id to page slugs #1746

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
41 changes: 41 additions & 0 deletions packages/common/src/core/_internal/computeItemLinks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { IItem } from "@esri/arcgis-rest-types";
import { IRequestOptions } from "@esri/arcgis-rest-request";
import { UserSession } from "@esri/arcgis-rest-auth";
import { getItemHomeUrl } from "../../urls";
import { IHubEntityLinks } from "../../core/types";
import { getItemIdentifier } from "../../items";
import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl";
import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url";
import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils";

/**
* Compute the links that get appended to a Hub Initiative
* search result and entity
*
* @param item
* @param requestOptions
*/
export function computeItemLinks(
item: IItem,
requestOptions: IRequestOptions
): IHubEntityLinks {
let token: string;
if (requestOptions.authentication) {
const session: UserSession = requestOptions.authentication as UserSession;
token = session.token;
}

return {
self: getItemHomeUrl(item.id, requestOptions),
siteRelative: getHubRelativeUrl(
item.type,
// use slug if available, otherwise id
getItemIdentifier(item),
item.typeKeywords
),
siteRelativeEntityType: getHubRelativeUrl(item.type),
// no SEO for workspace, so we always use id instead of slug
workspaceRelative: getRelativeWorkspaceUrl(item.type, item.id),
thumbnail: getItemThumbnailUrl(item, requestOptions, token),
};
}
25 changes: 3 additions & 22 deletions packages/common/src/initiative-templates/_internal/computeLinks.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { UserSession } from "@esri/arcgis-rest-auth";
import { IRequestOptions } from "@esri/arcgis-rest-request";
import { IItem } from "@esri/arcgis-rest-types";
import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils";
import { getRelativeWorkspaceUrl, IHubEntityLinks } from "../../core";
import { getItemIdentifier } from "../../items";
import { getItemThumbnailUrl } from "../../resources";
import { getItemHomeUrl } from "../../urls";
import { IHubEntityLinks } from "../../core";
import { computeItemLinks } from "../../core/_internal/computeItemLinks";

/**
* Compute the links that get appended to a Hub Initiative Template
Expand All @@ -19,20 +15,5 @@ export function computeLinks(
item: IItem,
requestOptions: IRequestOptions
): IHubEntityLinks {
let token: string;
if (requestOptions.authentication) {
const session: UserSession = requestOptions.authentication as UserSession;
token = session.token;
}

return {
self: getItemHomeUrl(item.id, requestOptions),
siteRelative: getHubRelativeUrl(item.type, getItemIdentifier(item)),
siteRelativeEntityType: getHubRelativeUrl(item.type),
workspaceRelative: getRelativeWorkspaceUrl(
item.type,
getItemIdentifier(item)
),
thumbnail: getItemThumbnailUrl(item, requestOptions, token),
};
return computeItemLinks(item, requestOptions);
}
28 changes: 4 additions & 24 deletions packages/common/src/initiatives/_internal/computeLinks.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { IItem } from "@esri/arcgis-rest-types";
import { computeItemLinks } from "../../core/_internal/computeItemLinks";
import { IRequestOptions } from "@esri/arcgis-rest-request";
import { UserSession } from "@esri/arcgis-rest-auth";
import { getItemHomeUrl } from "../../urls";
import { IHubEntityLinks } from "../../core/types";
import { getItemIdentifier } from "../../items";
import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl";
import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url";
import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils";
import { IItem } from "@esri/arcgis-rest-types";
import { IHubEntityLinks } from "../../core";

/**
* Compute the links that get appended to a Hub Initiative
Expand All @@ -19,20 +14,5 @@ export function computeLinks(
item: IItem,
requestOptions: IRequestOptions
): IHubEntityLinks {
let token: string;
if (requestOptions.authentication) {
const session: UserSession = requestOptions.authentication as UserSession;
token = session.token;
}

return {
self: getItemHomeUrl(item.id, requestOptions),
siteRelative: getHubRelativeUrl(item.type, getItemIdentifier(item)),
siteRelativeEntityType: getHubRelativeUrl(item.type),
workspaceRelative: getRelativeWorkspaceUrl(
item.type,
getItemIdentifier(item)
),
thumbnail: getItemThumbnailUrl(item, requestOptions, token),
};
return computeItemLinks(item, requestOptions);
}
13 changes: 10 additions & 3 deletions packages/common/src/items/getItemIdentifier.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { IItem } from "@esri/arcgis-rest-portal";
import { keywordSlugToUriSlug } from "./_internal/slugConverters";
import { appendIdToSlug } from "./slugs";

/**
* Consistent means to get an item's identifier - either the slug or the id
* @param item
* @returns
*/
export function getItemIdentifier(item: IItem): string {
const slug = item.properties?.slug;
return slug ? keywordSlugToUriSlug(slug) : item.id;
export function getItemIdentifier(
item: IItem,
includeIdInSlug = false
): string {
const { id, properties } = item;
const slug = properties?.slug;
return slug
? keywordSlugToUriSlug(includeIdInSlug ? appendIdToSlug(slug, id) : slug)
: id;
}
29 changes: 29 additions & 0 deletions packages/common/src/items/slugs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { IItem } from "@esri/arcgis-rest-types";
import { slugify } from "../utils";
import { TYPEKEYWORD_SLUG_PREFIX, truncateSlug } from "./_internal/slugs";
import { uriSlugToKeywordSlug } from "./_internal/slugConverters";
import { isGuid } from "../utils/is-guid";

const SLUG_ID_SEPARATOR = "~";

/**
* Create a slug, namespaced to an org and accounting for the 256 character limit
Expand Down Expand Up @@ -61,6 +64,11 @@ export function getItemBySlug(
slug: string,
requestOptions: IRequestOptions
): Promise<IItem> {
const id = parseIdFromSlug(slug);
if (id) {
// no need to do a typekeyword search if we have an id
return getItem(id, requestOptions);
}
const slugKeyword = uriSlugToKeywordSlug(slug);
return findItemsBySlug({ slug: slugKeyword }, requestOptions).then(
(results) => {
Expand Down Expand Up @@ -159,3 +167,24 @@ export function getUniqueSlug(
throw Error(`Error in getUniqueSlug ${e}`);
});
}

/**
* parse out the id from a slug
* @param slug
* @returns
*/
export const parseIdFromSlug = (slug: string) => {
// try to parse the id from the slug
const parts = slug.split(SLUG_ID_SEPARATOR);
return parts.length === 2 && isGuid(parts[1]) ? parts[1] : undefined;
};

/**
* append an id to a slug
* @param slug
* @param id
* @returns
*/
export const appendIdToSlug = (slug: string, id: string) => {
return `${slug}${SLUG_ID_SEPARATOR}${id}`;
};
31 changes: 15 additions & 16 deletions packages/common/src/pages/_internal/computeLinks.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { IItem } from "@esri/arcgis-rest-types";
import { IRequestOptions } from "@esri/arcgis-rest-request";
import { UserSession } from "@esri/arcgis-rest-auth";
import { IHubEntityLinks } from "../../core/types";
import { getItemIdentifier } from "../../items";
import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl";
import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url";
import { computeItemLinks } from "../../core/_internal/computeItemLinks";
import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils";
import { getItemHomeUrl } from "../../urls";
import { getItemIdentifier } from "../../items/getItemIdentifier";

/**
* Compute the links that get appended to a Hub Site
Expand All @@ -19,18 +16,20 @@ export function computeLinks(
item: IItem,
requestOptions: IRequestOptions
): IHubEntityLinks {
let token: string;
if (requestOptions.authentication) {
const session: UserSession = requestOptions.authentication as UserSession;
token = session.token;
}

const links = computeItemLinks(item, requestOptions);
// re-compute the site relative link to include the id
// NOTE: when we expand this beyond pages we should drop this override
// and just pass true to getItemIdentifier in computeItemLinks
const siteRelative = getHubRelativeUrl(
item.type,
getItemIdentifier(item, true),
item.typeKeywords
);
return {
self: getItemHomeUrl(item.id, requestOptions),
siteRelative: getHubRelativeUrl(item.type, item.id, item.typeKeywords),
siteRelativeEntityType: getHubRelativeUrl("page"),
...links,
// add id to site relative link
siteRelative,
// add the layout relative link
layoutRelative: `/pages/${item.id}/edit`,
workspaceRelative: getRelativeWorkspaceUrl(item.type, item.id),
thumbnail: getItemThumbnailUrl(item, requestOptions, token),
};
}
29 changes: 5 additions & 24 deletions packages/common/src/projects/_internal/computeLinks.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,19 @@
import { IItem } from "@esri/arcgis-rest-types";
import { computeItemLinks } from "../../core/_internal/computeItemLinks";
import { IRequestOptions } from "@esri/arcgis-rest-request";
import { UserSession } from "@esri/arcgis-rest-auth";
import { getItemHomeUrl } from "../../urls";
import { IHubEntityLinks } from "../../core/types";
import { getItemIdentifier } from "../../items";
import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils";
import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl";
import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url";
import { IItem } from "@esri/arcgis-rest-types";
import { IHubEntityLinks } from "../../core";

/**
* Compute the links that get appended to a Hub Project
* search result and entity
*
* @param item
* @param requestOptions
* @returns
*/
export function computeLinks(
item: IItem,
requestOptions: IRequestOptions
): IHubEntityLinks {
let token: string;
if (requestOptions.authentication) {
const session: UserSession = requestOptions.authentication as UserSession;
token = session.token;
}

return {
self: getItemHomeUrl(item.id, requestOptions),
siteRelative: getHubRelativeUrl(item.type, getItemIdentifier(item)),
siteRelativeEntityType: getHubRelativeUrl(item.type),
workspaceRelative: getRelativeWorkspaceUrl(
item.type,
getItemIdentifier(item)
),
thumbnail: getItemThumbnailUrl(item, requestOptions, token),
};
return computeItemLinks(item, requestOptions);
}
19 changes: 5 additions & 14 deletions packages/common/src/sites/_internal/computeLinks.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { IItem } from "@esri/arcgis-rest-types";
import { IRequestOptions } from "@esri/arcgis-rest-request";
import { UserSession } from "@esri/arcgis-rest-auth";
import { IHubEntityLinks } from "../../core/types";
import { getItemIdentifier } from "../../items";
import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl";
import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url";
import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils";
import { computeItemLinks } from "../../core/_internal/computeItemLinks";

/**
* Compute the links that get appended to a Hub Site
Expand All @@ -18,18 +15,12 @@ export function computeLinks(
item: IItem,
requestOptions: IRequestOptions
): IHubEntityLinks {
let token: string;
if (requestOptions.authentication) {
const session: UserSession = requestOptions.authentication as UserSession;
token = session.token;
}

const links = computeItemLinks(item, requestOptions);
return {
...links,
// for sites we use the site's url as the self link
self: item.url,
siteRelative: getHubRelativeUrl(item.type, item.id, item.typeKeywords),
siteRelativeEntityType: getHubRelativeUrl(item.type),
// add the layout relative link
layoutRelative: "/edit",
workspaceRelative: getRelativeWorkspaceUrl(item.type, item.id),
thumbnail: getItemThumbnailUrl(item, requestOptions, token),
};
}
41 changes: 13 additions & 28 deletions packages/common/src/templates/_internal/computeLinks.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { IItem } from "@esri/arcgis-rest-types";
import { IRequestOptions } from "@esri/arcgis-rest-request";
import { UserSession } from "@esri/arcgis-rest-auth";
import { getItemHomeUrl } from "../../urls";
import { IHubEntityLinks } from "../../core/types";
import { getItemIdentifier } from "../../items";
import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils";
import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl";
import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url";
import { computeItemLinks } from "../../core/_internal/computeItemLinks";

/**
* Compute the links that get appended to a Hub Template
Expand All @@ -19,32 +14,22 @@ export function computeLinks(
item: IItem,
requestOptions: IRequestOptions
): IHubEntityLinks {
let token: string;
if (requestOptions.authentication) {
const session: UserSession = requestOptions.authentication as UserSession;
token = session.token;
}
const links = computeItemLinks(item, requestOptions);

// If a solution template is deployed, we don't support
// managing it in the workspace, so we kick users to AGO
const isDeployed = item.typeKeywords?.includes("Deployed");
const itemHomeUrl = getItemHomeUrl(item.id, requestOptions);
const siteRelativeUrl = getHubRelativeUrl(
item.type,
getItemIdentifier(item),
item.typeKeywords
);
const { self, siteRelative, workspaceRelative } = links;
// templates have an advanced edit link
const advancedEditRelative = `${(siteRelative as string)
.split("/")
.slice(0, -1)
.join("/")}/edit/advanced`;
return {
self: itemHomeUrl,
siteRelative: siteRelativeUrl,
siteRelativeEntityType: getHubRelativeUrl(item.type),
workspaceRelative: isDeployed
? itemHomeUrl
: getRelativeWorkspaceUrl(item.type, getItemIdentifier(item)),
advancedEditRelative: `${siteRelativeUrl
.split("/")
.slice(0, -1)
.join("/")}/edit/advanced`,
thumbnail: getItemThumbnailUrl(item, requestOptions, token),
...links,
// handle deployed templates
workspaceRelative: isDeployed ? self : workspaceRelative,
// add advanced edit relative link
advancedEditRelative,
};
}
Loading