Skip to content

Commit

Permalink
feat: refactor entity schema implementation (#1203)
Browse files Browse the repository at this point in the history
This PR refactors entity uiSchemas to be exported as functions rather than consts. This allows us to add "dynamic" logic directly to our uiSchemas based on the entity and context that are already being passed in.
  • Loading branch information
juliannemarik authored Sep 11, 2023
1 parent f6d7943 commit 88cdd2b
Show file tree
Hide file tree
Showing 57 changed files with 3,328 additions and 2,328 deletions.
4 changes: 2 additions & 2 deletions packages/common/src/content/HubContent.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { IArcGISContext } from "../ArcGISContext";
import { HubItemEntity } from "../core/HubItemEntity";

import { EditorType } from "../core/schemas/types";
import {
IEditorConfig,
IWithEditorBehavior,
Expand All @@ -15,6 +14,7 @@ import { getEditorConfig } from "../core/schemas/getEditorConfig";
import { IEntityEditorContext } from "../core/types/HubEntityEditor";
import { cloneObject } from "../util";
import { editorToContent } from "./edit";
import { ContentEditorType } from "./_internal/ContentSchema";

export class HubContent
extends HubItemEntity<IHubEditableContent>
Expand Down Expand Up @@ -98,7 +98,7 @@ export class HubContent
*/
async getEditorConfig(
i18nScope: string,
type: EditorType
type: ContentEditorType
): Promise<IEditorConfig> {
// delegate to the schema subsystem
return getEditorConfig(i18nScope, type, this.entity, this.context);
Expand Down
260 changes: 147 additions & 113 deletions packages/common/src/content/_internal/ContentUiSchemaEdit.ts
Original file line number Diff line number Diff line change
@@ -1,135 +1,169 @@
import { IUiSchema } from "../../core";
import { IArcGISContext } from "../../ArcGISContext";
import { IHubContent } from "../../core/types";
import { getTagItems } from "../../core/schemas/internal/getTagItems";
import { getCategoryItems } from "../../core/schemas/internal/getCategoryItems";
import { getLocationExtent } from "../../core/schemas/internal/getLocationExtent";
import { getLocationOptions } from "../../core/schemas/internal/getLocationOptions";

/**
* @private
* constructs the complete edit uiSchema for Hub Content.
* This defines how the schema properties should be
* rendered in the content editing experience
*/
export const uiSchema: IUiSchema = {
type: "Layout",
elements: [
{
type: "Section",
labelKey: "{{i18nScope}}.sections.basic.title",
elements: [
// title
{
labelKey: "{{i18nScope}}.fields.title.label",
scope: "/properties/name",
type: "Control",
options: {
helperText: {
labelKey: "{{i18nScope}}.fields.title.hint",
},
messages: [
{
type: "ERROR",
keyword: "required",
icon: true,
labelKey: "{{i18nScope}}.fields.title.requiredError",
export const buildUiSchema = async (
i18nScope: string,
entity: IHubContent,
context: IArcGISContext
): Promise<IUiSchema> => {
return {
type: "Layout",
elements: [
{
type: "Section",
labelKey: `${i18nScope}.sections.basic.title`,
elements: [
// title
{
labelKey: `${i18nScope}.fields.title.label`,
scope: "/properties/name",
type: "Control",
options: {
helperText: {
labelKey: `${i18nScope}.fields.title.hint`,
},
],
messages: [
{
type: "ERROR",
keyword: "required",
icon: true,
labelKey: `${i18nScope}.fields.title.requiredError`,
},
],
},
},
},
// summary
{
labelKey: "{{i18nScope}}.fields.summary.label",
scope: "/properties/summary",
type: "Control",
options: {
control: "hub-field-input-input",
type: "textarea",
helperText: {
labelKey: "{{i18nScope}}.fields.summary.hint",
// summary
{
labelKey: `${i18nScope}.fields.summary.label`,
scope: "/properties/summary",
type: "Control",
options: {
control: "hub-field-input-input",
type: "textarea",
helperText: {
labelKey: `${i18nScope}.fields.summary.hint`,
},
},
},
},
// description
{
labelKey: "{{i18nScope}}.fields.description.label",
scope: "/properties/description",
type: "Control",
options: {
control: "hub-field-input-input",
type: "textarea",
helperText: {
labelKey: "{{i18nScope}}.fields.description.hint",
// description
{
labelKey: `${i18nScope}.fields.description.label`,
scope: "/properties/description",
type: "Control",
options: {
control: "hub-field-input-input",
type: "textarea",
helperText: {
labelKey: `${i18nScope}.fields.description.hint`,
},
},
},
},
// thumbnail image
{
labelKey: "{{i18nScope}}.fields._thumbnail.label",
scope: "/properties/_thumbnail",
type: "Control",
options: {
control: "hub-field-input-image-picker",
maxWidth: 727,
maxHeight: 484,
aspectRatio: 1.5,
helperText: {
labelKey: "{{i18nScope}}.fields._thumbnail.helperText",
// thumbnail image
{
labelKey: `${i18nScope}.fields._thumbnail.label`,
scope: "/properties/_thumbnail",
type: "Control",
options: {
control: "hub-field-input-image-picker",
imgSrc: entity.thumbnailUrl,
maxWidth: 727,
maxHeight: 484,
aspectRatio: 1.5,
helperText: {
labelKey: `${i18nScope}.fields._thumbnail.helperText`,
},
},
},
},
// tags
{
labelKey: "{{i18nScope}}.fields.tags.label",
scope: "/properties/tags",
type: "Control",
options: {
control: "hub-field-input-combobox",
allowCustomValues: true,
selectionMode: "multiple",
placeholderIcon: "label",
helperText: { labelKey: "{{i18nScope}}.fields.tags.hint" },
// tags
{
labelKey: `${i18nScope}.fields.tags.label`,
scope: "/properties/tags",
type: "Control",
options: {
control: "hub-field-input-combobox",
items: await getTagItems(
entity,
context.portal.id,
context.hubRequestOptions
),
allowCustomValues: true,
selectionMode: "multiple",
placeholderIcon: "label",
helperText: { labelKey: `${i18nScope}.fields.tags.hint` },
},
},
},
// categories
{
labelKey: "{{i18nScope}}.fields.categories.label",
scope: "/properties/categories",
type: "Control",
options: {
control: "hub-field-input-combobox",
allowCustomValues: false,
selectionMode: "multiple",
placeholderIcon: "select-category",
helperText: {
labelKey: "{{i18nScope}}.fields.categories.agolHint", // TODO: hint should describe whether it can be set on Enterprise or Online
// categories
{
labelKey: `${i18nScope}.fields.categories.label`,
scope: "/properties/categories",
type: "Control",
options: {
control: "hub-field-input-combobox",
items: await getCategoryItems(
context.portal.id,
context.hubRequestOptions
),
allowCustomValues: false,
selectionMode: "multiple",
placeholderIcon: "select-category",
helperText: {
labelKey: `${i18nScope}.fields.categories.agolHint`, // TODO: hint should describe whether it can be set on Enterprise or Online
},
},
},
},
// license
{
labelKey: "{{i18nScope}}.fields.license.label",
scope: "/properties/licenseInfo",
type: "Control",
options: {
control: "arcgis-hub-license-picker",
helperText: {
labelKey: "{{i18nScope}}.fields.license.helperText",
// license
{
labelKey: `${i18nScope}.fields.license.label`,
scope: "/properties/licenseInfo",
type: "Control",
options: {
control: "arcgis-hub-license-picker",
helperText: {
labelKey: `${i18nScope}.fields.license.helperText`,
},
},
},
},
],
},
// location section
{
type: "Section",
labelKey: "{{i18nScope}}.sections.location.label",
options: {
helperText: {
labelKey: "{{i18nScope}}.sections.location.helperText",
},
],
},
elements: [
{
scope: "/properties/location",
type: "Control",
options: {
control: "hub-field-input-location-picker",
// location section
{
type: "Section",
labelKey: `${i18nScope}.sections.location.label`,
options: {
helperText: {
labelKey: `${i18nScope}.sections.location.helperText`,
},
},
],
},
],
elements: [
{
scope: "/properties/location",
type: "Control",
options: {
control: "hub-field-input-location-picker",
extent: await getLocationExtent(
entity,
context.hubRequestOptions
),
options: await getLocationOptions(
entity,
context.portal.name,
context.hubRequestOptions
),
},
},
],
},
],
};
};
4 changes: 1 addition & 3 deletions packages/common/src/core/schemas/getEditorConfig.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { IEditorConfig } from "../behaviors/IWithEditorBehavior";
import { IArcGISContext } from "../../ArcGISContext";
import { ConfigurableEntity } from "./internal/ConfigurableEntity";
import { getEditorConfigOptions } from "./internal/getEditorConfigOptions";
import { getEntityEditorSchemas } from "./internal/getEntityEditorSchemas";
import { EditorType } from "./types";

Expand All @@ -19,6 +18,5 @@ export async function getEditorConfig(
entity: ConfigurableEntity,
context: IArcGISContext
): Promise<IEditorConfig> {
const options = await getEditorConfigOptions(type, entity, context);
return getEntityEditorSchemas(i18nScope, type, options);
return getEntityEditorSchemas(i18nScope, type, entity, context);
}
Loading

0 comments on commit 88cdd2b

Please sign in to comment.