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(): association group creation form and permission #1413

Merged
merged 27 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
de59356
feat(): add permissions for association group
jordantsanz Feb 14, 2024
614810b
feat(): add build defaults centralized system?
jordantsanz Feb 14, 2024
cfcefff
feat(): add editorModule func
jordantsanz Feb 20, 2024
0e3106f
fix(): rebase
jordantsanz Feb 20, 2024
0d2f80a
fix(): typing for defaults
jordantsanz Feb 20, 2024
8695c27
fix(): integrate with getWellKNownGroup
jordantsanz Feb 20, 2024
5e1c9ac
test(): add tests for buildDefaults
jordantsanz Feb 20, 2024
0b6499a
fix(): update translation strings
jordantsanz Feb 20, 2024
c00440f
fix(): remove text defaults
jordantsanz Feb 20, 2024
32d35a8
feat(): add buildDefaults to all entities and stat card
jordantsanz Feb 21, 2024
bec2315
Merge branch 'master' of github.com:Esri/hub.js into f/9089-associati…
jordantsanz Feb 21, 2024
090a708
refactor(): implement createViewGroup and createEditGroup defaults
jordantsanz Feb 21, 2024
e87b49f
fix(): fix coverage
jordantsanz Feb 21, 2024
30b8f02
feat(): add new util for assoc group initialization
jordantsanz Feb 22, 2024
3ac94b1
fix(): update getWellKNownGroup
jordantsanz Feb 26, 2024
aa0bbeb
fix(): update default group
jordantsanz Feb 26, 2024
2bd019f
fix(): add protected call
jordantsanz Feb 26, 2024
829b84a
fix(): add protected call
jordantsanz Feb 26, 2024
30084de
fix(): use protectGroup
jordantsanz Feb 26, 2024
65949bc
refactor(): make cleaner
jordantsanz Feb 26, 2024
54e03f8
fix(): rebump jobs
jordantsanz Feb 26, 2024
f55f091
fix(): pr feedback, doc and update setEntityAssocGroup
jordantsanz Feb 26, 2024
9b76033
fix(): remove priv and update membershipAccess default
jordantsanz Feb 26, 2024
c876d41
Merge branch 'master' of github.com:Esri/hub.js into f/9089-associati…
jordantsanz Feb 26, 2024
b04e023
fix(): add disabled options if no priv
jordantsanz Feb 26, 2024
6f3db7b
test(): 100% coverage
jordantsanz Feb 27, 2024
db258d1
Merge branch 'master' into f/9089-association-group
jordantsanz Feb 28, 2024
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
1 change: 1 addition & 0 deletions packages/common/src/associations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from "./getPendingEntitiesQuery";
export * from "./getRequestingEntitiesQuery";
export * from "./getReferencedEntityIds";
export * from "./wellKnownAssociationCatalogs";
export * from "./setEntityAssociationGroup";
// Note: we expose "requestAssociation" under 2 names.
// These actions are functionally equivalent, but we want
// to make the intent more clear to the consumer.
Expand Down
47 changes: 47 additions & 0 deletions packages/common/src/associations/setEntityAssociationGroup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { IArcGISContext } from "../ArcGISContext";
import { IHubGroup, getTypeFromEntity } from "../core";
import { HubEntity } from "../core/types/HubEntity";
import { updateHubEntity } from "../core/updateHubEntity";
import { setProp } from "../objects";

/**
* Utility to create a relationship between an entity and a group, setting the group as
* the entity's association group. This adds the entity-specific association keyword to the association group,
* and it adds the association definition to the original entity.
* @param entity
* @param group
* @param context
* @returns
*/
export async function setEntityAssociationGroup(
entity: HubEntity,
group: IHubGroup,
context: IArcGISContext
): Promise<HubEntity> {
const type = getTypeFromEntity(entity);

// 1. Add the association marker to the group entity
// if we don't already have it
const associationKeyword = `${type}|${entity.id}`;
if (!group.typeKeywords.includes(associationKeyword)) {
group.typeKeywords = [...group.typeKeywords, `${type}|${entity.id}`];
}

await updateHubEntity("group", group, context);

// 2. construct and persist the initiative's association definition
const associations = {
groupId: group.id,
rules: {
schemaVersion: 1,
query: {
targetEntity: "item",
filters: [{ predicates: [{ group: group.id }] }],
},
},
};
setProp("associations", associations, entity);
const updatedEntity = await updateHubEntity(type, entity, context);

return updatedEntity;
}
13 changes: 13 additions & 0 deletions packages/common/src/core/schemas/internal/getCardEditorSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { filterSchemaToUiSchema } from "./filterSchemaToUiSchema";
import { CardEditorOptions } from "./EditorOptions";
import { cloneObject } from "../../../util";
import { IArcGISContext } from "../../../ArcGISContext";
import { ICardEditorModuleType } from "../types";

/**
* get the editor schema and uiSchema defined for a layout card.
Expand Down Expand Up @@ -36,6 +37,7 @@ export async function getCardEditorSchemas(
let uiSchema;
let schemaPromise;
let uiSchemaPromise;
let defaults;

switch (cardType) {
case "stat":
Expand All @@ -55,8 +57,19 @@ export async function getCardEditorSchemas(
options,
context
);

// if we have buildDefaults, build the defaults
// TODO: when first implementing buildDefaults for initiative templates, remove the ignore line

/* istanbul ignore next */
if ((uiSchemaModuleResolved as ICardEditorModuleType).buildDefaults) {
defaults = (
uiSchemaModuleResolved as ICardEditorModuleType
).buildDefaults(i18nScope, options, context);
}
}
);

break;
case "follow":
// get correct module
Expand Down
131 changes: 121 additions & 10 deletions packages/common/src/core/schemas/internal/getEditorSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
IConfigurationSchema,
IUiSchema,
IEditorConfig,
IConfigurationValues,
IEntityEditorModuleType,
} from "../types";
import { filterSchemaToUiSchema } from "./filterSchemaToUiSchema";
import { SiteEditorType } from "../../../sites/_internal/SiteSchema";
Expand Down Expand Up @@ -46,14 +48,15 @@ export async function getEditorSchemas(
// the entity type and the provided editor type
let schema: IConfigurationSchema;
let uiSchema: IUiSchema;
let defaults: IConfigurationValues;
switch (editorType) {
case "site":
const { SiteSchema } = await import(
"../../../sites/_internal/SiteSchema"
);
schema = cloneObject(SiteSchema);

const siteModule = await {
const siteModule: IEntityEditorModuleType = await {
"hub:site:edit": () =>
import("../../../sites/_internal/SiteUiSchemaEdit"),
"hub:site:create": () =>
Expand All @@ -71,6 +74,18 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
// TODO: when implementing buildDefaults for sites, remove the ignore line

/* istanbul ignore next */
if (siteModule.buildDefaults) {
defaults = await siteModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;
// ----------------------------------------------------
case "discussion":
Expand All @@ -79,7 +94,7 @@ export async function getEditorSchemas(
);
schema = cloneObject(DiscussionSchema);

const discussionModule = await {
const discussionModule: IEntityEditorModuleType = await {
"hub:discussion:edit": () =>
import("../../../discussions/_internal/DiscussionUiSchemaEdit"),
"hub:discussion:create": () =>
Expand All @@ -93,6 +108,18 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
// TODO: when first implementing buildDefaults for discussions, remove the ignore line

/* istanbul ignore next */
if (discussionModule.buildDefaults) {
defaults = await discussionModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;
// ----------------------------------------------------
case "project":
Expand All @@ -101,7 +128,7 @@ export async function getEditorSchemas(
);
schema = cloneObject(ProjectSchema);

const projectModule = await {
const projectModule: IEntityEditorModuleType = await {
"hub:project:edit": () =>
import("../../../projects/_internal/ProjectUiSchemaEdit"),
"hub:project:create": () =>
Expand All @@ -114,6 +141,18 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
// TODO: when first implementing buildDefaults for projects, remove the ignore line

/* istanbul ignore next */
if (projectModule.buildDefaults) {
defaults = await projectModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;
// ----------------------------------------------------
case "initiative":
Expand All @@ -122,7 +161,7 @@ export async function getEditorSchemas(
);
schema = cloneObject(InitiativeSchema);

const initiativeModule = await {
const initiativeModule: IEntityEditorModuleType = await {
"hub:initiative:edit": () =>
import("../../../initiatives/_internal/InitiativeUiSchemaEdit"),
"hub:initiative:create": () =>
Expand All @@ -134,6 +173,18 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
// TODO: when first implementing buildDefaults for initiatives, remove the ignore line

/* istanbul ignore next */
if (initiativeModule.buildDefaults) {
defaults = await initiativeModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;
// ----------------------------------------------------
case "page":
Expand All @@ -142,7 +193,7 @@ export async function getEditorSchemas(
);
schema = cloneObject(PageSchema);

const pageModule = await {
const pageModule: IEntityEditorModuleType = await {
"hub:page:edit": () =>
import("../../../pages/_internal/PageUiSchemaEdit"),
}[type as PageEditorType]();
Expand All @@ -152,6 +203,18 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
// TODO: when first implementing buildDefaults for pages, remove the ignore line

/* istanbul ignore next */
if (pageModule.buildDefaults) {
defaults = await pageModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;
// ----------------------------------------------------
case "content":
Expand All @@ -160,7 +223,7 @@ export async function getEditorSchemas(
);
schema = cloneObject(ContentSchema);

const contentModule = await {
const contentModule: IEntityEditorModuleType = await {
"hub:content:edit": () =>
import("../../../content/_internal/ContentUiSchemaEdit"),
"hub:content:discussions": () =>
Expand All @@ -174,6 +237,18 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
// TODO: when first implementing buildDefaults for content, remove the ignore line

/* istanbul ignore next */
if (contentModule.buildDefaults) {
defaults = await contentModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;
// ----------------------------------------------------
case "template":
Expand All @@ -182,7 +257,7 @@ export async function getEditorSchemas(
);
schema = cloneObject(TemplateSchema);

const templateModule = await {
const templateModule: IEntityEditorModuleType = await {
"hub:template:edit": () =>
import("../../../templates/_internal/TemplateUiSchemaEdit"),
}[type as TemplateEditorType]();
Expand All @@ -192,6 +267,18 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
// TODO: when first implementing buildDefaults for templates, remove the ignore line

/* istanbul ignore next */
if (templateModule.buildDefaults) {
defaults = await templateModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;
// ----------------------------------------------------
case "group":
Expand All @@ -200,9 +287,11 @@ export async function getEditorSchemas(
);
schema = cloneObject(GroupSchema);

const groupModule = await {
const groupModule: IEntityEditorModuleType = await {
"hub:group:create:followers": () =>
import("../../../groups/_internal/GroupUiSchemaCreateFollowers"),
"hub:group:create:association": () =>
import("../../../groups/_internal/GroupUiSchemaCreateAssociation"),
"hub:group:create:view": () =>
import("../../../groups/_internal/GroupUiSchemaCreateView"),
"hub:group:create:edit": () =>
Expand All @@ -220,14 +309,23 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
if (groupModule.buildDefaults) {
jordantsanz marked this conversation as resolved.
Show resolved Hide resolved
defaults = await groupModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;

case "initiativeTemplate":
const { InitiativeTemplateSchema } = await import(
"../../../initiative-templates/_internal/InitiativeTemplateSchema"
);
schema = cloneObject(InitiativeTemplateSchema);
const initiativeTemplateModule = await {
const initiativeTemplateModule: IEntityEditorModuleType = await {
"hub:initiativeTemplate:edit": () =>
import(
"../../../initiative-templates/_internal/InitiativeTemplateUiSchemaEdit"
Expand All @@ -240,6 +338,18 @@ export async function getEditorSchemas(
context
);

// if we have the buildDefaults fn, then construct the defaults
// TODO: when first implementing buildDefaults for initiative templates, remove the ignore line

/* istanbul ignore next */
if (initiativeTemplateModule.buildDefaults) {
defaults = await initiativeTemplateModule.buildDefaults(
i18nScope,
options as EntityEditorOptions,
context
);
}

break;

case "card":
Expand All @@ -251,10 +361,11 @@ export async function getEditorSchemas(
);
schema = result.schema;
uiSchema = result.uiSchema;
defaults = result.defaults;
}

// filter out properties not used in the UI schema
schema = filterSchemaToUiSchema(schema, uiSchema);

return Promise.resolve({ schema, uiSchema });
return Promise.resolve({ schema, uiSchema, defaults });
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ import {
* @param context
* @returns
*/
export const buildUiSchema = (
export const buildUiSchema = async (
i18nScope: string,
config: EntityEditorOptions,
context: IArcGISContext
): IUiSchema => {
): Promise<IUiSchema> => {
return {
type: "Layout",
elements: [
Expand Down
Loading
Loading