From 5c074c4a6e45f708fd451d78e5351dd54f918341 Mon Sep 17 00:00:00 2001 From: Julianna Apicella <42875581+juliannaeapicella@users.noreply.github.com> Date: Wed, 18 Oct 2023 15:49:34 -0400 Subject: [PATCH] feat(hub-common): add support for discussion settings for entities affects: @esri/hub-common, @esri/hub-discussions ISSUES CLOSED: 7412 --- packages/common/src/core/HubItemEntity.ts | 5 ++- .../core/traits/IWithDiscussionsSettings.ts | 8 ++++ .../src/core/traits/IWithEntitySettings.ts | 10 +++++ packages/common/src/core/traits/index.ts | 2 + .../common/src/core/types/IHubDiscussion.ts | 9 +++- .../discussions/_internal/getPropertyMap.ts | 9 +++- packages/common/src/discussions/api/types.ts | 10 ++--- packages/common/src/discussions/edit.ts | 44 ++++++++++++++++++- packages/common/src/discussions/fetch.ts | 7 ++- .../internal/getDefaultEntitySettings.ts | 12 +++++ packages/discussions/src/types.ts | 2 +- 11 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 packages/common/src/core/traits/IWithDiscussionsSettings.ts create mode 100644 packages/common/src/core/traits/IWithEntitySettings.ts create mode 100644 packages/common/src/utils/internal/getDefaultEntitySettings.ts diff --git a/packages/common/src/core/HubItemEntity.ts b/packages/common/src/core/HubItemEntity.ts index 31af057502c..d6d7803ebc3 100644 --- a/packages/common/src/core/HubItemEntity.ts +++ b/packages/common/src/core/HubItemEntity.ts @@ -41,6 +41,7 @@ import { AssociationType, IAssociationInfo } from "../associations/types"; import { listAssociations } from "../associations/listAssociations"; import { addAssociation } from "../associations/addAssociation"; import { removeAssociation } from "../associations/removeAssociation"; +import { IEntitySetting, IWithEntitySettings } from ".."; const FEATURED_IMAGE_FILENAME = "featuredImage.png"; @@ -56,8 +57,10 @@ export abstract class HubItemEntity IWithPermissionBehavior, IWithDiscussionsBehavior, IWithFollowersBehavior, - IWithAssociationBehavior + IWithAssociationBehavior, + IWithEntitySettings { + entitySettings: Omit & { id?: string }; protected context: IArcGISContext; protected entity: T; protected isDestroyed: boolean = false; diff --git a/packages/common/src/core/traits/IWithDiscussionsSettings.ts b/packages/common/src/core/traits/IWithDiscussionsSettings.ts new file mode 100644 index 00000000000..7cfb5633816 --- /dev/null +++ b/packages/common/src/core/traits/IWithDiscussionsSettings.ts @@ -0,0 +1,8 @@ +import { IDiscussionsSettings } from "../../discussions"; + +/** + * Discussions-related settings + */ +export interface IWithDiscussionsSettings { + discussionSettings: IDiscussionsSettings; +} diff --git a/packages/common/src/core/traits/IWithEntitySettings.ts b/packages/common/src/core/traits/IWithEntitySettings.ts new file mode 100644 index 00000000000..bf8f3a58d91 --- /dev/null +++ b/packages/common/src/core/traits/IWithEntitySettings.ts @@ -0,0 +1,10 @@ +import { IEntitySetting } from "../../discussions"; + +/** + * Entity settings + */ +export interface IWithEntitySettings { + entitySettings: Omit & { + id?: string; + }; +} diff --git a/packages/common/src/core/traits/index.ts b/packages/common/src/core/traits/index.ts index 90928faac65..dfa060fae12 100644 --- a/packages/common/src/core/traits/index.ts +++ b/packages/common/src/core/traits/index.ts @@ -6,3 +6,5 @@ export * from "./IWithPermissions"; export * from "./IWithCatalog"; export * from "./IWithViewSettings"; export * from "./IWithDiscussions"; +export * from "./IWithEntitySettings"; +export * from "./IWithDiscussionsSettings"; diff --git a/packages/common/src/core/types/IHubDiscussion.ts b/packages/common/src/core/types/IHubDiscussion.ts index c7361cb32e1..3ce35aab696 100644 --- a/packages/common/src/core/types/IHubDiscussion.ts +++ b/packages/common/src/core/types/IHubDiscussion.ts @@ -1,4 +1,8 @@ -import { IWithPermissions, IWithSlug } from "../traits"; +import { + IWithDiscussionsSettings, + IWithPermissions, + IWithSlug, +} from "../traits"; import { IHubItemEntity, IHubItemEntityEditor } from "./IHubItemEntity"; /** @@ -8,6 +12,7 @@ import { IHubItemEntity, IHubItemEntityEditor } from "./IHubItemEntity"; export interface IHubDiscussion extends IHubItemEntity, IWithSlug, - IWithPermissions {} + IWithPermissions, + IWithDiscussionsSettings {} export type IHubDiscussionEditor = IHubItemEntityEditor & {}; diff --git a/packages/common/src/discussions/_internal/getPropertyMap.ts b/packages/common/src/discussions/_internal/getPropertyMap.ts index 899d3449678..f1ba850f93c 100644 --- a/packages/common/src/discussions/_internal/getPropertyMap.ts +++ b/packages/common/src/discussions/_internal/getPropertyMap.ts @@ -12,10 +12,17 @@ export function getPropertyMap(): IPropertyMap[] { const map = getBasePropertyMap(); // Type specific mappings - map.push({ entityKey: "prompt", storeKey: "data.prompt" }); + map.push({ + entityKey: "prompt", + storeKey: "data.prompt", + }); map.push({ entityKey: "location", storeKey: "item.properties.location", }); + map.push({ + entityKey: "entitySettings.settings.discussions", + storeKey: "discussionSettings", + }); return map; } diff --git a/packages/common/src/discussions/api/types.ts b/packages/common/src/discussions/api/types.ts index 50ed6569cf9..634a60c8695 100644 --- a/packages/common/src/discussions/api/types.ts +++ b/packages/common/src/discussions/api/types.ts @@ -1037,7 +1037,7 @@ export interface IEntitySetting IWithTimestamps { id: string; type: EntitySettingType; - settings: IEntityContentSettings; + settings: IEntitySettings; } /** @@ -1050,9 +1050,9 @@ export enum EntitySettingType { /** * @export - * @interface IEntityContentSettings + * @interface IEntitySettings */ -export interface IEntityContentSettings { +export interface IEntitySettings { discussions?: IDiscussionsSettings; } @@ -1081,7 +1081,7 @@ export interface IRemoveSettingResponse { export interface ICreateSetting { id: string; type: EntitySettingType; - settings: IEntityContentSettings; + settings: IEntitySettings; } /** @@ -1089,7 +1089,7 @@ export interface ICreateSetting { * @interface IUpdateSetting */ export interface IUpdateSetting { - settings: Partial; + settings: Partial; } /** diff --git a/packages/common/src/discussions/edit.ts b/packages/common/src/discussions/edit.ts index 7e5b807f446..1b51241f732 100644 --- a/packages/common/src/discussions/edit.ts +++ b/packages/common/src/discussions/edit.ts @@ -3,11 +3,20 @@ import { IUserItemOptions, removeItem } from "@esri/arcgis-rest-portal"; import { IHubDiscussion } from "../core/types"; import { createModel, getModel, updateModel } from "../models"; import { constructSlug, getUniqueSlug, setSlugKeyword } from "../items/slugs"; -import { IModel, cloneObject, setDiscussableKeyword } from "../index"; +import { + EntitySettingType, + IModel, + cloneObject, + createSetting, + removeSetting, + setDiscussableKeyword, + updateSetting, +} from "../index"; import { PropertyMapper } from "../core/_internal/PropertyMapper"; import { getPropertyMap } from "./_internal/getPropertyMap"; import { computeProps } from "./_internal/computeProps"; import { DEFAULT_DISCUSSION, DEFAULT_DISCUSSION_MODEL } from "./defaults"; +import { getDefaultEntitySettings } from "../utils/internal/getDefaultEntitySettings"; /** * @private @@ -45,6 +54,16 @@ export async function createDiscussion( discussion.typeKeywords, discussion.isDiscussable ); + // initialize discussion settings + discussion.discussionSettings = await createSetting({ + data: { + id: discussion.id, + type: EntitySettingType.CONTENT, + settings: getDefaultEntitySettings(EntitySettingType.CONTENT), + }, + }).then((result) => { + return result.settings.discussions; + }); // Map discussion object onto a default discussion Model const mapper = new PropertyMapper, IModel>( getPropertyMap() @@ -98,6 +117,26 @@ export async function updateDiscussion( // now map back into a discussion and return that let updatedDiscussion = mapper.storeToEntity(updatedModel, discussion); updatedDiscussion = computeProps(model, updatedDiscussion, requestOptions); + if (updatedDiscussion.discussionSettings) { + updateSetting({ + id: updatedDiscussion.id, + data: { + settings: { + discussions: updatedDiscussion.discussionSettings, + }, + }, + }); + } else { + updatedDiscussion.discussionSettings = await createSetting({ + data: { + id: updatedDiscussion.id, + type: EntitySettingType.CONTENT, + settings: getDefaultEntitySettings(EntitySettingType.CONTENT), + }, + }).then((result) => { + return result.settings.discussions; + }); + } // the casting is needed because modelToObject returns a `Partial` // where as this function returns a `T` return updatedDiscussion as IHubDiscussion; @@ -114,6 +153,9 @@ export async function deleteDiscussion( id: string, requestOptions: IUserRequestOptions ): Promise { + removeSetting({ id }).catch(() => { + // surpressing error... + }); const ro = { ...requestOptions, ...{ id } } as IUserItemOptions; await removeItem(ro); return; diff --git a/packages/common/src/discussions/fetch.ts b/packages/common/src/discussions/fetch.ts index a63006f0d10..5e696855761 100644 --- a/packages/common/src/discussions/fetch.ts +++ b/packages/common/src/discussions/fetch.ts @@ -3,10 +3,11 @@ import { IItem, getItem } from "@esri/arcgis-rest-portal"; import { IHubDiscussion } from "../core/types"; import { fetchModelFromItem } from "../models"; import { getItemBySlug } from "../items/slugs"; -import { IModel, isGuid } from "../index"; +import { EntitySettingType, IModel, fetchSetting, isGuid } from "../index"; import { PropertyMapper } from "../core/_internal/PropertyMapper"; import { getPropertyMap } from "./_internal/getPropertyMap"; import { computeProps } from "./_internal/computeProps"; +import { getDefaultEntitySettings } from "../utils/internal/getDefaultEntitySettings"; /** * @private @@ -45,6 +46,10 @@ export async function convertItemToDiscussion( requestOptions: IRequestOptions ): Promise { const model = await fetchModelFromItem(item, requestOptions); + await fetchSetting({ id: item.id }).then((settings) => { + model.entitySettings = + settings ?? getDefaultEntitySettings(EntitySettingType.CONTENT); + }); const mapper = new PropertyMapper, IModel>( getPropertyMap() ); diff --git a/packages/common/src/utils/internal/getDefaultEntitySettings.ts b/packages/common/src/utils/internal/getDefaultEntitySettings.ts new file mode 100644 index 00000000000..1e7516c40d3 --- /dev/null +++ b/packages/common/src/utils/internal/getDefaultEntitySettings.ts @@ -0,0 +1,12 @@ +import { EntitySettingType, IEntitySettings } from "../../discussions"; + +export function getDefaultEntitySettings( + type: EntitySettingType +): IEntitySettings { + return { + discussions: { + allowedChannelIds: [], + allowedLocations: [], + }, + }; +} diff --git a/packages/discussions/src/types.ts b/packages/discussions/src/types.ts index e1f709ebf3f..ce7dc2923ad 100644 --- a/packages/discussions/src/types.ts +++ b/packages/discussions/src/types.ts @@ -76,7 +76,7 @@ export { IRemoveChannelActivityParams, IEntitySetting, EntitySettingType, - IEntityContentSettings, + IEntitySettings, IDiscussionsSettings, IRemoveSettingResponse, ICreateSetting,