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(): adds entity discussion settings #1221

Merged
merged 9 commits into from
Oct 2, 2023
48 changes: 18 additions & 30 deletions package-lock.json

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

5 changes: 5 additions & 0 deletions packages/common/src/content/_internal/ContentBusinessRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const ContentPermissions = [
"hub:content:workspace:overview",
"hub:content:workspace:dashboard",
"hub:content:workspace:details",
"hub:content:workspace:discussion",
"hub:content:workspace:settings",
"hub:content:manage",
] as const;
Expand Down Expand Up @@ -67,6 +68,10 @@ export const ContentPermissionPolicies: IPermissionPolicy[] = [
permission: "hub:content:workspace:details",
dependencies: ["hub:content:edit"],
},
{
permission: "hub:content:workspace:discussion",
dependencies: ["hub:content:edit"],
},
{
permission: "hub:content:workspace:settings",
dependencies: ["hub:content:edit"],
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/content/_internal/ContentSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type ContentEditorType = (typeof ContentEditorTypes)[number];
export const ContentEditorTypes = [
"hub:content:edit",
"hub:content:settings",
"hub:content:discussions",
] as const;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { IHubEditableContent } from "../../core/types";
import { IArcGISContext } from "../../ArcGISContext";
import { IUiSchema } from "../../core/schemas/types";

/**
* @private
* settings uiSchema for Hub Discussions - this
* defines how the schema properties should be
* rendered in the Discussions settings experience
*/
export const buildUiSchema = async (
i18nScope: string,
entity: IHubEditableContent,
context: IArcGISContext
): Promise<IUiSchema> => {
return {
type: "Layout",
elements: [
{
type: "Section",
labelKey: `${i18nScope}.sections.discussions.label`,
elements: [
{
labelKey: `${i18nScope}.fields.discussable.label`,
scope: "/properties/isDiscussable",
type: "Control",
options: {
control: "hub-field-input-radio",
labels: [
`{{${i18nScope}.fields.discussable.enabled.label:translate}}`,
`{{${i18nScope}.fields.discussable.disabled.label:translate}}`,
],
descriptions: [
`{{${i18nScope}.fields.discussable.enabled.description:translate}}`,
`{{${i18nScope}.fields.discussable.disabled.description:translate}}`,
],
icons: ["speech-bubbles", "circle-disallowed"],
},
},
],
},
],
};
};
3 changes: 3 additions & 0 deletions packages/common/src/content/_internal/computeProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getContentEditUrl, getHubRelativeUrl } from "./internalContentUtils";
import { IHubLocation } from "../../core/types/IHubLocation";
import { IHubEditableContent } from "../../core/types/IHubEditableContent";
import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl";
import { isDiscussable } from "../../discussions";
import {
hasServiceCapability,
ServiceCapabilities,
Expand Down Expand Up @@ -72,6 +73,8 @@ export function computeProps(
: deriveLocationFromItemExtent(model.item.extent);
}

content.isDiscussable = isDiscussable(content);

if (enrichments.server) {
content.serverExtractCapability = hasServiceCapability(
ServiceCapabilities.EXTRACT,
Expand Down
10 changes: 10 additions & 0 deletions packages/common/src/content/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { getPropertyMap } from "./_internal/getPropertyMap";
import { cloneObject } from "../util";
import { IModel } from "../types";
import { getProp } from "../objects/get-prop";
import { setDiscussableKeyword } from "../discussions";
import { modelToHubEditableContent } from "./fetch";
import { getService, parseServiceUrl } from "@esri/arcgis-rest-feature-layer";
import { updateServiceDefinition } from "@esri/arcgis-rest-service-admin";
Expand Down Expand Up @@ -58,6 +59,11 @@ export async function createContent(
// this expansion solves the typing somehow
const content = { /* ...DEFAULT_PROJECT, */ ...partialContent };

content.typeKeywords = setDiscussableKeyword(
content.typeKeywords,
content.isDiscussable
);

// Map project object onto a default project Model
const mapper = new PropertyMapper<Partial<IHubEditableContent>, IModel>(
getPropertyMap()
Expand Down Expand Up @@ -103,6 +109,10 @@ export async function updateContent(
// to properly handle other types like PDFs that don't have JSON data
const item = await getItem(content.id, requestOptions);
const model: IModel = { item };
content.typeKeywords = setDiscussableKeyword(
content.typeKeywords,
content.isDiscussable
);
// create the PropertyMapper
const mapper = new PropertyMapper<Partial<IHubEditableContent>, IModel>(
getPropertyMap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export async function getEntityEditorSchemas(
import("../../../sites/_internal/SiteUiSchemaCreate"),
"hub:site:followers": () =>
import("../../../sites/_internal/SiteUiSchemaFollowers"),
"hub:site:discussions": () =>
import("../../../sites/_internal/SiteUiSchemaDiscussions"),
}[type as SiteEditorType]();
uiSchema = await siteModule.buildUiSchema(
i18nScope,
Expand All @@ -77,6 +79,8 @@ export async function getEntityEditorSchemas(
import("../../../discussions/_internal/DiscussionUiSchemaEdit"),
"hub:discussion:create": () =>
import("../../../discussions/_internal/DiscussionUiSchemaCreate"),
"hub:discussion:settings": () =>
import("../../../discussions/_internal/DiscussionUiSchemaSettings"),
}[type as DiscussionEditorType]();
uiSchema = await discussionModule.buildUiSchema(
i18nScope,
Expand Down Expand Up @@ -153,6 +157,8 @@ export async function getEntityEditorSchemas(
const contentModule = await {
"hub:content:edit": () =>
import("../../../content/_internal/ContentUiSchemaEdit"),
"hub:content:discussions": () =>
import("../../../content/_internal/ContentUiSchemaDiscussions"),
"hub:content:settings": () =>
import("../../../content/_internal/ContentUiSchemaSettings"),
}[type as ContentEditorType]();
Expand All @@ -174,6 +180,8 @@ export async function getEntityEditorSchemas(
import("../../../groups/_internal/GroupUiSchemaEdit"),
"hub:group:settings": () =>
import("../../../groups/_internal/GroupUiSchemaSettings"),
"hub:group:discussions": () =>
import("../../../groups/_internal/GroupUiSchemaDiscussions"),
}[type as GroupEditorType]();
uiSchema = await groupModule.buildUiSchema(
i18nScope,
Expand Down
5 changes: 5 additions & 0 deletions packages/common/src/core/types/IHubGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ export interface IHubGroup extends IHubEntityBase, IWithPermissions {
*/
tags?: string[];

/**
* System configurable typekeywords
*/
typeKeywords?: string[];

/**
* Group thumbnail url (read-only)
*/
Expand Down
4 changes: 3 additions & 1 deletion packages/common/src/core/types/IHubSite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,6 @@ export interface IHubSite
legacyTeams: string[];
}

export type IHubSiteEditor = IHubItemEntityEditor<IHubSite> & {};
export type IHubSiteEditor = IHubItemEntityEditor<IHubSite> & {
_discussions?: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type DiscussionEditorType = (typeof DiscussionEditorTypes)[number];
export const DiscussionEditorTypes = [
"hub:discussion:edit",
"hub:discussion:create",
"hub:discussion:settings",
] as const;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,29 +182,6 @@ export const buildUiSchema = async (
},
],
},
{
type: "Section",
labelKey: `${i18nScope}.sections.settings.label`,
elements: [
{
labelKey: `${i18nScope}.fields.discussable.label`,
scope: "/properties/isDiscussable",
type: "Control",
options: {
control: "hub-field-input-radio",
labels: [
`{{${i18nScope}.fields.discussable.enabled.label:translate}}`,
`{{${i18nScope}.fields.discussable.disabled.label:translate}}`,
],
descriptions: [
`{{${i18nScope}.fields.discussable.enabled.description:translate}}`,
`{{${i18nScope}.fields.discussable.disabled.description:translate}}`,
],
icons: ["speech-bubbles", "circle-disallowed"],
},
},
],
},
],
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { IHubDiscussion } from "../../core/types";
import { IArcGISContext } from "../../ArcGISContext";
import { IUiSchema } from "../../core/schemas/types";

/**
* @private
* settings uiSchema for Hub Discussions - this
* defines how the schema properties should be
* rendered in the Discussions settings experience
*/
export const buildUiSchema = async (
i18nScope: string,
entity: IHubDiscussion,
context: IArcGISContext
): Promise<IUiSchema> => {
return {
type: "Layout",
elements: [
{
type: "Section",
labelKey: `${i18nScope}.sections.settings.label`,
elements: [
{
labelKey: `${i18nScope}.fields.discussable.label`,
scope: "/properties/isDiscussable",
type: "Control",
options: {
control: "hub-field-input-radio",
labels: [
`{{${i18nScope}.fields.discussable.enabled.label:translate}}`,
`{{${i18nScope}.fields.discussable.disabled.label:translate}}`,
],
descriptions: [
`{{${i18nScope}.fields.discussable.enabled.description:translate}}`,
`{{${i18nScope}.fields.discussable.disabled.description:translate}}`,
],
icons: ["speech-bubbles", "circle-disallowed"],
},
},
],
},
],
};
};
2 changes: 1 addition & 1 deletion packages/common/src/discussions/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function setDiscussableKeyword(
typeKeywords: string[],
discussable: boolean
): string[] {
const updatedTypeKeywords = typeKeywords.filter(
const updatedTypeKeywords = (typeKeywords || []).filter(
(typeKeyword: string) => typeKeyword !== CANNOT_DISCUSS
);
if (!discussable) {
Expand Down
Loading