Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@agility/app-sdk

Package Overview
Dependencies
Maintainers
3
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@agility/app-sdk - npm Package Compare versions

Comparing version 2.0.0-rc1 to 2.0.0-rc10

.vscode/settings.json

494

dist/index.d.ts

@@ -1,5 +0,489 @@

export * from "./types";
export * from "./useAgilityAppSDK";
export * from "./useAgilityPreInstall";
export * from "./methods";
export * from "./hooks";
interface IAppConfigValue {
name: string;
value: string;
}
interface IAppEventParam<T> {
appID: string;
operationID: string;
operationType: "initialize" | "context" | "updateConfigurationValue" | "getContentItem" | "openModal" | "selectAssets" | "persistData" | "refresh" | "setHeight" | "setFieldValue" | "addFieldListener" | "onFieldChanged" | "getAppInstall" | "preInstall" | "installApp" | "preInstall" | "setExtraConfigValues" | "removeFieldListener" | "getSelectedItems" | "addSelectedItemListener" | "onSelectedItemChange" | "removeSelectedItemListener" | "setVisibility" | "getPageItem";
error?: string;
arg?: T;
}
interface IAppInstallContext {
appID: string;
configuration: {
[name: string]: string;
};
}
interface IContentItem {
contentID: number;
referenceName: string;
values: {
[key: string]: any;
};
}
interface FieldSettingsType {
AvailableSettingAttributes: string[];
Description: string;
DesignerOnly: boolean;
Editable: boolean;
FieldID: string;
FieldName: string;
FieldType: string;
HiddenField: boolean;
IsDataField: boolean;
ItemOrder: number;
Label: string;
LabelHelpDescription: string;
Settings: any;
}
interface IContentModel {
AllowTagging: boolean;
ContentDefinitionID: number;
CustomIFrameUrl: string | null;
CustomInputForm: boolean;
CustomScripts: string | null;
EnableLikes: boolean;
EnableRating: boolean;
EnableVoting: boolean;
FieldSettings: FieldSettingsType[];
LegacyInputForm: boolean;
ReferenceName: string;
Title: string;
}
interface IField {
id: string;
label: string;
typeName: string;
name: string;
value: any;
description?: string;
required: boolean;
readOnly: boolean;
}
interface IInstance {
guid: string;
websiteName: string;
}
interface IPageItem {
ParentPageID: number;
ParentPageItemContainerID: number;
PageTemplateID: number;
PageTemplateName: string | null;
ContentItemID: number;
DetachPageContent: boolean;
RequiresAuthentication: boolean;
IncludeInStatsTracking: boolean;
ExcludeFromOutputCache: boolean;
CustomAnalyticsScript: string;
PagePath: string | null;
PageType: number;
PageHierarchyPosition: number;
PageName: string;
URL: string | null;
MetaKeyWords: string;
MetaTagsRaw: string;
MetaTags: string;
LanguageCode: string;
DomainName: string;
IsValid: boolean;
PageTemplateRelativePath: string;
StyleSheets: any[];
PreviewUrl: string | null;
RequiresApproval: boolean;
ItemContainerID: number;
CurrentItemID: number;
StagingItemID: number;
PublishedItemID: number;
CreatedDate: string;
PublishedDate: string;
ReleaseDate: string;
PullDate: string;
Mode: number;
State: number;
Menu: any;
CurrentUserCanDelete: boolean;
CurrentUserCanEdit: boolean;
CurrentUserCanDesign: boolean;
CurrentUserCanManage: boolean;
DynamicPageContentViewID: number;
DynamicPageContentDefinitionID: number;
DynamicPageContentViewFieldName: string | null;
DynamicPageContentViewSort: string | null;
DynamicPageContentViewFilter: string | null;
DynamicPageTitle: string | null;
DynamicPageName: string | null;
DynamicPageMenuText: string | null;
DynamicPageVisibleOnMenu: boolean;
DynamicPageVisibleOnSitemap: boolean;
DigitalChannelID: number;
Title: string;
CreatedAuthor: IAuthorType;
PublishedAuthor: IAuthorType;
Users: any[];
Teams: any[];
Notifications: any[];
}
interface IAuthorType {
UserID: number;
EmailAddress: string;
UserName: string;
FirstName: string;
LastName: string;
FullName: string;
IsDeleted: boolean;
IsTeamUser: boolean;
TeamID: number | null;
DefaultUILanguage: string;
IsSuspended: boolean;
}
interface IContextParam {
app: IAppInstallContext;
instance: IInstance;
locale: string;
field?: IField;
contentItem?: IContentItem;
contentModel?: IContentModel;
pageItem?: IPageItem;
}
/**
* Sets a height for the iframe and can accept px or %.
*
*/
interface IAppHeightValue {
height: number | string;
}
interface IAppDataPersistValue {
key: string;
value: string;
}
interface IAppFieldValue {
name?: string;
value: string;
}
interface IModalParam<T> {
title: string;
props?: any;
callback: (result: T) => void;
}
interface IAppInstallInfo {
appInstall: {
appInstallID?: number;
websiteID: number;
appRegistrationID: number;
isDeleted: boolean;
isDisabled: boolean;
installedByUserID?: number;
installedOn?: string;
versionID: number;
};
appConfiguration: {
appConfigurationID?: number;
appInstallID: number;
name?: string;
value?: string;
label?: string;
type?: string;
isHiddenSetting: boolean;
}[];
}
interface IInstallApp {
profileId: string;
}
interface IInstallContext {
configuration: IConfig[];
}
interface IConfig {
Label: string;
Name: string;
Type: string;
Value: any;
}
interface SelectedItem {
contentItemID: number | string;
contentViewID: number;
createdDate: string;
itemContainerID: number | string;
state: string;
title: string;
userName: string;
}
interface IAppSelectedItems {
selectedItems: SelectedItem[];
}
interface IAssetItem {
ContainerEdgeUrl?: string;
ContainerID?: number;
ContainerOriginUrl?: string;
ContentType?: string;
DateModified?: string;
EdgeUrl?: string;
FileName?: string;
GridThumbnailID?: number;
GridThumbnailSuffix?: string | number;
HasChildren?: boolean;
IsDeleted?: boolean;
IsFolder?: boolean;
IsImage?: boolean;
IsSvg?: boolean;
MediaGroupingID?: number;
MediaGroupingName?: string | number;
MediaGroupingSortOrder?: number;
MediaID?: number;
MetaData?: any;
ModifiedBy?: number;
ModifiedByName?: string;
OriginKey?: string;
OriginUrl?: string;
Size?: number;
ThumbnailUrl?: string;
}
/**
* Sets a visibility for the iframe and can accept px or %.
*
*/
interface IAppVisibility {
fieldID: string;
visibility: boolean;
}
interface AgilityAddSKReturn {
initializing: boolean;
appInstallContext: IAppInstallContext | null;
instance: IInstance | null;
locale: string | null;
field: IField | null;
contentItem: IContentItem | null;
contentModel: IContentModel | null;
pageItem: IPageItem | null;
}
/**
* The main hook for using the Agility App SDK.
*
* @returns {AgilityAddSKReturn}
*/
declare const useAgilityAppSDK: () => AgilityAddSKReturn;
interface AgilityPreInstallReturn {
configuration: IConfig[];
}
/**
* The pre install hook, used to pass configuration values to the install screen.
*
* @returns {AgilityPreInstallReturn}
*/
declare const useAgilityPreInstall: () => AgilityPreInstallReturn;
/**
* Updates a configuration value for the current app. This will be persisted by Agility.
*
* @param {Props} {key, value}
* @returns {Promise<void>}
*/
declare const updateConfigurationValue: ({ name, value }: IAppConfigValue) => (Promise<IAppConfigValue> | undefined);
interface Props$3 {
key: string;
value: string;
}
/**
* Persists value for the current app. This will be persisted per user by Agility.
*
* @param {Props} {key, value}
* @returns {Promise<void>}
*/
declare const persistData: ({ key, value }: Props$3) => Promise<IAppDataPersistValue> | void;
declare const index_d$3_persistData: typeof persistData;
declare const index_d$3_updateConfigurationValue: typeof updateConfigurationValue;
declare namespace index_d$3 {
export {
index_d$3_persistData as persistData,
index_d$3_updateConfigurationValue as updateConfigurationValue,
};
}
/**
* Gets the contentItem from the current context.
* This is meant to be used on Custom Field or Content Item Sidebar Panel app.
*
* @returns {Promise<IContentItem>}
*/
declare const getContentItem: () => (Promise<IContentItem> | undefined);
interface Props$2 {
fieldName: string;
onChange: (fieldValue: any) => void;
}
/**
* addFieldListener
* attach a listener to a particular fieldName
* On every update of the subscribed field, it fires the onFieldChanged operation
* @param { fieldName, onChange }
*/
declare const addFieldListener: ({ fieldName, onChange }: Props$2) => void;
/**
* setFieldValue
* sends a message out to the iframe channel with a a name and value
* @param param0
* @returns
*/
declare const setFieldValue: ({ name, value }: IAppFieldValue) => void;
interface Props$1 {
fieldName: string;
}
/**
* removeFieldListener
* attach a listener to a particular fieldName
* On every update of the subscribed field, it fires the onFieldChanged operation
* @param { fieldName, onChange }
*/
declare const removeFieldListener: ({ fieldName }: Props$1) => void;
/**
* Gets the selecteditems from the current context.
* This is meant to be used on the Content List Item Sidebar Panel app.
*
* @returns {Promise<SelectedItems[]>}
*/
declare const getSelectedItems: () => (Promise<SelectedItem[]> | undefined);
interface Props {
onChange: (fieldValue: any) => void;
}
/**
* addSelectedItemListener
* attach a listener to a particular fieldName
* On every update of the subscribed field, it fires the onFieldChanged operation
* @param { onChange }
*/
declare const addSelectedItemListener: ({ onChange }: Props) => void;
/**
* removeSelectedItemListener
*/
declare const removeSelectedItemListener: () => void;
declare const index_d$2_addFieldListener: typeof addFieldListener;
declare const index_d$2_addSelectedItemListener: typeof addSelectedItemListener;
declare const index_d$2_getContentItem: typeof getContentItem;
declare const index_d$2_getSelectedItems: typeof getSelectedItems;
declare const index_d$2_removeFieldListener: typeof removeFieldListener;
declare const index_d$2_removeSelectedItemListener: typeof removeSelectedItemListener;
declare const index_d$2_setFieldValue: typeof setFieldValue;
declare namespace index_d$2 {
export {
index_d$2_addFieldListener as addFieldListener,
index_d$2_addSelectedItemListener as addSelectedItemListener,
index_d$2_getContentItem as getContentItem,
index_d$2_getSelectedItems as getSelectedItems,
index_d$2_removeFieldListener as removeFieldListener,
index_d$2_removeSelectedItemListener as removeSelectedItemListener,
index_d$2_setFieldValue as setFieldValue,
};
}
/**
* selectAssets
* Selects assets for the current context
* This is meant to be used on the pages dashboard or content dashboard.
*
* @returns {Promise<any>}
*/
declare const selectAssets: ({ title, singleSelectOnly, callback }: {
title: any;
singleSelectOnly: any;
callback: any;
}) => void;
declare const index_d$1_selectAssets: typeof selectAssets;
declare namespace index_d$1 {
export {
index_d$1_selectAssets as selectAssets,
};
}
/**
* Gets the pageItem from the current context
*
* @returns {Promise<IPageItem>}
*/
declare const getPageItem: () => (Promise<IPageItem> | undefined);
declare const index_d_getPageItem: typeof getPageItem;
declare namespace index_d {
export {
index_d_getPageItem as getPageItem,
};
}
/**
* setHeight
* sends a message out to the iframe channel with a numeric height
* @param height
*/
declare const setHeight: ({ height }: IAppHeightValue) => void;
/**
* openModal
* Opens a modal popup with the given name.
* This is meant to be used on Custom Field or Content Item Sidebar Panel app.
* The callback will be called when the modal's "OK" button is clicked and the modal has been closed.
*
* @template T
* @param {Props<T>} { name, props, callback }
*/
declare const openModal: <T>({ title, callback }: IModalParam<T>) => void;
/**
* Gets the app install data for the current app. Includes app configuration values
*
* @returns {Promise<IAppInstallInfo>}
*/
declare const getAppInstall: () => Promise<IAppInstallInfo> | null;
/**
* refresh
* sends a message out to the iframe channel with a numeric height
*/
declare const refresh: () => void;
/**
* setVisibility
* sends a message out to the iframe channel with a numeric height
* @param visibility - true wills how the iframe, false will hdie the iframe
*/
declare const setVisibility: ({ fieldID, visibility }: IAppVisibility) => void;
/**
* Sends back any extra configuration to the install flow in the content manager.
*
* @param {Props} {key, value}
* @returns {Promise<void>}
*/
declare const setExtraConfigValues: (configuration: IConfig[]) => (Promise<IConfig[]> | undefined);
declare const useElementHeight: <T extends HTMLElement = HTMLDivElement>() => [(node: T | null) => void, number];
export { IAppConfigValue, IAppDataPersistValue, IAppEventParam, IAppFieldValue, IAppHeightValue, IAppInstallContext, IAppInstallInfo, IAppSelectedItems, IAppVisibility, IAssetItem, IConfig, IContentItem, IContentModel, IContextParam, IField, IInstallApp, IInstallContext, IInstance, IModalParam, IPageItem, SelectedItem, index_d$1 as assetsMethods, index_d$3 as configMethods, index_d$2 as contentItemMethods, getAppInstall, openModal, index_d as pageMethods, refresh, setExtraConfigValues, setHeight, setVisibility, useAgilityAppSDK, useAgilityPreInstall, useElementHeight };

29

package.json
{
"name": "@agility/app-sdk",
"version": "2.0.0-rc1",
"version": "2.0.0-rc10",
"description": "JavaScript library for building Agility CMS apps.",
"main": "dist/index.js",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/index.d.ts",
"scripts": {
"clean": "rm -rf ./dist",
"build": "yarn clean && tsc",
"build:clean": "yarn clean",
"build:rollup": "rollup -c",
"build": "run-s build:*",
"prepare": "yarn build",
"watch": "tsc -w",
"watch": "rollup -c -w",
"test": "echo \"Error: no test specified\" && exit 1"

@@ -24,11 +28,24 @@ },

"devDependencies": {
"@rollup/plugin-commonjs": "^24.1.0",
"@rollup/plugin-node-resolve": "^15.0.2",
"@rollup/plugin-typescript": "^11.1.0",
"@types/node": "^18.15.11",
"@types/react": "^18.0.34",
"@types/react-dom": "^18.0.11",
"npm-run-all": "^4.1.5",
"react": "^18.2.0",
"rxjs": "^7.8.0",
"react-dom": "^18.2.0",
"rollup": "^3.21.3",
"rollup-plugin-dts": "^5.3.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.34.1",
"rxjs": "^7.8.1",
"ts-loader": "^9.4.2",
"typescript": "^5.0.4"
},
"dependencies": {}
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
# Agility CMS App SDK
This is a JavaScript SDK for building UI Apps for Agility CMS.
This is a React SDK for building UI Apps for Agility CMS.
- [Features](#features)
- [How it Works](#how-it-works)
- [What you can Do](#what-you-can-do)
- [Getting Started](#getting-started)
- [Examples](#examples)
- [Set up the App Configuration](#set-up-your-app-configuration)
- [Set up a Custom Field](#set-up-your-custom-field)
- [Field SDK](#using-the-field-sdk) | [Properties](#field-sdk-properties) | [Methods](#field-sdk-methods)
- [Set up a Flyout](#set-up-a-flyout)
- [Flyout SDK](#using-the-flyout-sdk) | [Properties](#flyout-sdk-properties) | [Methods](#flyout-sdk-methods)
- [Styling your App](#styling-your-app)
### Local Development
## Features
- Build custom UIs that can be shown in Agility CMS
- Secure iFrame communication between the CMS and your app.
- Ability to define one or more custom fields and flyout actions.
- Supports modern frameworks such as React or Vue, as well as support for building Vanilla javascript apps.
- Support for additional UI components (such as Sidebar Apps) are **coming soon**!
## How it Works
The **App SDK** facilitates a communication layer between Agility CMS and a single-page app that will be loaded in an iFrame. Using the SDK allows you to easily integrate with the CMS using JavaScript.
## Advanced
If you wish to use yarn link with this project to debug locally:
At this time, only **Custom Fields** and **Flyouts** are supported, however there are plans to introduce new UI locations such as Sidebar components.
### What you can Do
Just rendering your UI in a content input form isn't enough. The **App SDK** allows you to:
- Render a custom field
- Set a custom field value
- Set the value of another field
- Run custom logic when another field changes
- Launch a flyout with a custom UI
- Retrieve `configValues` that were set when the app was installed (such as API Keys, etc.)
## Getting Started
### Prerequisites
You need to have an Agility instance and be comfortable writing JavaScript. You'll also need to deploy your app to a publicly accessible endpoint and register it in Agility CMS.
### What is in an App?
An App will contain a page with an `AppConfig` (which informs Agility CMS about the functionality of your app) and one or more custom UI's that will integrate with Agility CMS.
- **AppIndex** - This is your HTML page that will contain logic to show your UI component based on what App Location the CMS is requesting (i.e. `AppConfig`, `CustomField`, or `Flyout`)
- **AppConfig** - The component responsible registering the App in the CMS and establishing what user-definied `configValues` can be set.
- **CustomField(s)** - The UI components responsible for rendering a custom field for a Content Model or Page Module.
- **Flyout(s)** - The UI components responsible for rendering the details of a flyout that was opened from a Custom Field.
### Examples
We've put together a couple example Apps to help you get started.
- [React App for Agility CMS](https://github.com/agility/agility-cms-apps/tree/main/example/react)
- [Vanilla JS App for Agility CMS](https://github.com/agility/agility-cms-apps/tree/main/example/html)
### Installation
Install it using a package manager (recommended):
`npm install @agility/app-sdk` or `yarn add @agility/app-sdk`.
If you are building in Vanilla javascript, you can also reference a standalong package that can be used in a browser using a traditional `<script>` tag. In this case, the sdk can be accessed using a global variable by the name of `agilityAppSDK`.
```html
<!-- Use a specific version (i.e. 0.1.5) -->
<script type="text/javascript" src="https://unpkg.com/@agility/app-sdk@0.1.5/dist/agility-cms-app-sdk.browser.js"></script>
```
## Set up your App Index
When your App is installed in an Agility instance, Agility will automatically call your App by the URL it is hosted on.
Your root page for your App must contain logic to determine what UI component is being requested by the CMS. Then, it should render the component/logic appropriately.
An example of this in React `App.js`:
```javascript
import './App.css';
import agilityAppSDK from '@agility/app-sdk'
import BasicCustomField from './BasicCustomField';
import Flyout from './Flyout';
function App() {
const Components = {
BasicCustomField,
Flyout
}
const appConfig = {
name: 'Basic App',
version: '1',
configValues: [
{ name: 'apiKey', label: 'API Key', type: 'string'}
],
appComponents: [
{
location: agilityAppSDK.types.APP_LOCATION_CUSTOM_FIELD,
label: 'Basic Custom Field',
name: 'BasicCustomField',
componentToRender: 'BasicCustomField'
},
{
location: agilityAppSDK.types.APP_LOCATION_CUSTOM_FIELD,
label: 'Other Custom Field',
name: 'OtherCustomField',
componentToRender: 'BasicCustomField'
},
{
location: agilityAppSDK.types.APP_LOCATION_FLYOUT,
componentToRender: 'Flyout',
name: 'Flyout1'
}
]
};
const componentRequested = agilityAppSDK.resolveAppComponent(appConfig);
if(componentRequested === 'AppConfig') {
//provide the CMS information about your app configuration
agilityAppSDK.setAppConfig(appConfig);
} else {
//determine the React component we want to render based on what the CMS has requested...
const ComponentToRender = Components[componentRequested];
if(ComponentToRender) {
return <ComponentToRender appConfig={appConfig} />;
} else {
return <h2>Warning: App must be loaded within Agility CMS.</h2>
}
}
return null;
}
export default App;
cd THIS_PACKAGE
yarn link
yarn install
cd node_modules/react
yarn link
cd ../../node_modules/react-dom
yarn link
cd YOUR_PROJECT
yarn link PACKAGE_YOU_DEBUG_LOCALLY
yarn link react
yarn link react-dom
```
## Set up your App Configuration
When the App is initially installed or whenever Agility CMS loads, it needs to be able to access your `AppConfig`.
Then, when you are done
Your `AppConfig` must be in a specific format, and you must initialize it appropriately using the `setAppConfig` method from the SDK.
```javascript
const appConfig =
{
name: 'Basic App',
version: '1.0.0',
configValues: [
{ name: 'apiKey', label: 'API Key', type: 'string'}
],
appComponents: [
{
location: agilityAppSDK.types.APP_LOCATION_CUSTOM_FIELD,
name: 'BasicCustomField',
componentToRender: 'BasicCustomField',
label: 'Basic Custom Field',
},
{
location: agilityAppSDK.types.APP_LOCATION_FLYOUT,
name: 'Flyout1',
componentToRender: 'Flyout',
}
]
};
```
### App Configuration Parameters
>**`*`** Represents a required configuration parameter.
cd YOUR_PROJECT
yarn unlink "@agility/app-sdk"
yarn unlink react
yarn link react-dom
`name: <string> *`
cd THIS_PACKAGE
yarn unlink
cd node_modules/react
yarn unlink
cd ../../node_modules/react-dom
yarn unlink
The name of your App (will be displayed in Agiliity CMS).
***
`version: <string> *`
The version of your App (can be any string, will be displayed in Agility CMS).
***
`documentationLink: <string> *`
The URL to a hosted webpage that provides detailed information about this app. This will be accessible to users when they are installing your app within in instance.
***
`configValues: <objectArray>`
The (*optional*) configuration values you want to capture when a user installs the App.
`configValues[].name <string> *`
The reference name of the config value you want to capture.
`configValues[].label <string> *`
The friendly label of the config value you want to capture.
`configValues[].type <string> *`
The type of input that is expected. Valid values are `string` only at this time.
***
`appComponents <objectArray> *`
The array of components that your App supports. It *must* include a component with the *location* of `"AppConfig"`.
`appComponents[].location <string> *` => The location type of the custom field. Valid values are:
- `agilityAppSDK.types.APP_LOCATION_APP_CONFIG`
- `agilityAppSDK.types.APP_LOCATION_CUSTOM_FIELD`
- `agilityAppSDK.types.APP_LOCATION_FLYOUT`
`appComponents[].name <string> *`
The reference name of the UI component. For **Custom Fields**, this is used to store the name of the custom field type in your Models. For **Flyouts**, this represents a unique name for opening a specific flyout.
`appComponents[].componentToRender <string> *`
The name of your component that will be used to determine which UI component to render. This is returned from `agilityAppSDK.resolveAppComponent(appConfig)`.
`appComponents[].label <string> `
>Required for **Custom Fields** only
This is the friendly label of the **custom field** which is used in Models to display a list of all available custom fields.
***
### Using the App Configuration
Once you have established your App Configuration, you need to tell Agility CMS about it within your `AppConfig` component when requested.
`agilityAppSDK.setAppConfig(<appConfig>): void`
Sends a message to the CMS to inform it of our App.
An example of this:
```javascript
const componentRequested = agilityAppSDK.resolveAppComponent(appConfig);
if(componentRequested === 'AppConfig') {
//provide the CMS information about your app configuration
agilityAppSDK.setAppConfig(appConfig);
}
```
>**Note**: If your App does not notify the CMS about its configuration within *3 seconds* of being requested, we'll treat the App as non-responsive and prevent it from being used in the CMS.
## Set Up your Custom Field
Now that you have your **App Index** and **App Config** set up, the next step is to set up your custom field component(s).
An example of this in React `BasicCustomField.js`:
```javascript
import { useEffect, useState, useRef } from 'react';
import agilityAppSDK from '@agility/app-sdk'
function BasicCustomField() {
const [value, setValue] = useState("");
const [fieldLabel, setFieldLabel] = useState("");
const [configValues, setConfigValues] = useState({});
const [sdk, setSDK] = useState({})
const containerRef = useRef();
useEffect(() => {
agilityAppSDK.initializeField({ containerRef }).then((fieldSDK) => {
//set the SDK that we can use later...
setSDK(fieldSDK);
//set the actual value of the field
setValue(fieldSDK.field.value);
setFieldLabel(fieldSDK.field.label);
setConfigValues(fieldSDK.configValues);
fieldSDK.subscribeToFieldValueChanges({
fieldName: 'Title',
onChange: ({fieldName, fieldValue}) => {
//when the 'Title' changes, get notified, and do something...
console.log(fieldName, fieldValue);
}
})
});
}, []);
const updateValue = (newVal) => {
//update the react state
setValue(newVal);
//notify Agility CMS of the new value
sdk.updateFieldValue({ fieldValue: newVal });
}
const openCustomFlyout = () => {
sdk.openFlyout({
title: 'Flyout Title',
size: agilityAppSDK.types.APP_FLYOUT_SIZE_LARGE,
name: 'Flyout1',
onClose: (params) => {
//passes the parameters back from the app component that closed the flyout
console.log(params);
},
params: {
key: 'value'
}
})
}
return (
<div className="BasicCustomField" ref={containerRef}>
<label>
{fieldLabel}
<input style={{display: 'block', width: '100%'}} type="text" defaultValue={value} onChange={e => updateValue(e.target.value)} />
</label>
<p>API Key: {configValues.apiKey}</p>
<button onClick={openCustomFlyout}>Open Flyout</button>
</div>
);
}
export default BasicCustomField;
```
>The above example shows how you *initialize the field*, can *subscribe to other field changes*, *set the field value*, as well as *open a flyout*.
***
### Using the Field SDK
In order to interact with the CMS, you need to call:
```javascript
agilityAppSDK.initializeField({
containerRef: <HtmlElem>
}): Promise<fieldSDK>
```
This will return a `Promise` which will be resolved with the `fieldSDK` client that can be used to interact with the field.
```
fieldSDK <object>
```
The `fieldSDK` represents the object returned from `agilityAppSDK.initializeField` and the base SDK to use for interacting with custom fields and the content it is loaded on.
***
### Field SDK Properties
The following are the properties returned in the `fieldSDK` object:
`guid`
The guid of representing the Agility CMS instance calling this app.
***
`websiteName`
The website/instance name representing the Agility CMS instance calling this app.
***
`locale`
The current locale that the Agility CMS is in.
***
`field.value <string>`
The current value of the custom field.
***
`field.label <string>`
The label of the field as it appears in the Content Model/Page Module.
***
`field.name <string>`
The reference name for this field. This is defined when adding the field to your Content Model/Page Module.
***
`field.typeName <string>`
The field reference name of this specific custom field (as defined in `appConfig.appComponents`).
***
`field.description <string>`
The description of the field. This is defined when adding the field to your Content Model/Page Module.
***
`field.required <boolean>`
Determines if a field value is required in order to save the content item.
***
`field.readonly <boolean>`
Determines if a field is allowed to be edited. This could return as `false` if a user does not have permission to edit the field or this field is being rendered as part of a `Version History` view.
***
`configValues <object>`
The configuration values that have been set by the user who installed the App. This is based off the `configValues` that were set in your `AppConfig`.
***
### Field SDK Methods
The following represents the methods available to call from the `fieldsSDK`:
#### Updating a Field Value
```javascript
fieldSDK.updateFieldValue({
fieldValue: <string|number|decimal>,
fieldName: <string>
}): void
```
Sets a field value on the content item. If no `fieldName` is set, it will set the value for the current custom field being rendered.
>**Note**: When setting a `fieldName`, it should match the exact casing of the `apiName` for the field as shown in Agility CMS for the associated content model.
***
#### Subscribing to Field Value Changes
```javascript
fieldSDK.subscribeToFieldValueChanges({
fieldName: <string>,
onChange: <function>
}): void
```
Notifies when the value of a specific field **changes** on the content item. If a change occurs, the `onChange` function is called and passes the `fieldName <string>` and `fieldValue <string|number|decimal>` as parameters.
***
#### Open a Flyout
```javascript
fieldSDK.openFlyout({
title: <string>,
size: <string>,
name: <string>,
onClose: <function>,
params: <object>
}): void
```
Notifies the CMS to open a **Flyout** in the CMS and use a **Flyout** component from your App.
Open Flyout Parameters:
`title <string>`
The friendly title of the Flyout. It will be shown as the title of the Flyout in the CMS.
***
`size <string>`
The size of the Flyout to open. Valid values are:
- `agilityAppSDK.types.APP_FLYOUT_SIZE_SMALL`
- `agilityAppSDK.types.APP_FLYOUT_SIZE_LARGE`
***
`name <string>`
The unique name of your Flyout. This *must* correspond to a known Flyout component with a matching `name` in your `AppConfig`.
***
`onClose <function>`
The function callback for when the Flyout is programatically closed from within the target Flyout component. This is useful for scenarios where you need to get some input from a user interaction that occurred in the flyout back to the custom field that called it.
When the Flyout calls `closeFlyout`, any user defined `params` that were passed as an argument will be sent through as `params` in this `onClose` callback.
***
## Set up a Flyout
Flyouts allow you to show a UI outside of the content input form and are very useful for integrations where a user may need to interact with an external UI and you don't want that to take up too much space in the input form itself.
Flyouts work very similar to custom fields. You initialize the flyout (`agilityAppSDK.initializeFlyout`), which returns a `flyoutSDK` which can then be used to access some properties and methods.
An example of this in React `Flyout.js`
```javascript
import { useEffect, useRef, useState } from 'react';
import agilityAppSDK from '@agility/app-sdk';
function Flyout({ appConfig }) {
const containerRef = useRef();
const [sdk, setSDK] = useState({})
const [flyout, setFlyout] = useState({});
//const [configValues, setConfigValues] = useState({});
useEffect(() => {
agilityAppSDK.initializeFlyout({containerRef}).then((flyoutSDK) => {
setSDK(flyoutSDK);
setFlyout(flyoutSDK.flyout);
//You can also get access to this properties:
//setConfigValues(flyoutSDK.configValues);
})
}, [appConfig]);
const closeThisFlyout = () => {
sdk.closeFlyout({
params: {
'somevalue': 'was set'
}
})
}
return (
<div className="Flyout" ref={containerRef}>
{ sdk && sdk.initiator &&
<div>
<div>This is a custom flyout {flyout.title} that was initialized by the {sdk.initiator.name} field.</div>
<button onClick={closeThisFlyout}>Close Flyout</button>
</div>
}
</div>
);
}
export default Flyout;
```
### Using the Flyout SDK
In order to interact with the CMS, you need to call:
```javascript
agilityAppSDK.initializeFlyout({
containerRef: <HtmlElem>
}): Promise<flyoutSDK>
```
This will return a `Promise` which will be resolved with the `flyoutSDK` client that can be used to interact with the field.
```
flyoutSDK <object>
```
The `flyoutSDK` represents the object returned from `agilityAppSDK.initializeFlyout` and the base SDK to use for interacting with flyouts.
***
### Flyout SDK Properties
The `flyoutSDK` contains many of the same properties as the `fieldSDK`.
`guid`
The guid of representing the Agility CMS instance calling this app.
***
`websiteName`
The website/instance name representing the Agility CMS instance calling this app.
***
`locale`
The current locale that the Agility CMS is in.
***
`configValues <object>`
The configuration values that have been set by the user who installed the App. This is based off the `configValues` that were set in your `AppConfig`.
***
### Flyout SDK Methods
The following represents the methods available to call from the `flyoutSDK`:
#### Close Flyout
```javascript
flyoutSDK.closeFlyout({
pararms: <object>
}): void
```
Closes the flyout and passes the `params` object as parameter to the `onClose` callback from the custom field that initiated the flyout. This is useful for passing information set in a flyout back to the original custom field that initiated it.
The `params` object can be anything you want.
## Styling your App
Since apps are loaded as iframes, they will not inherit any styles from Agility CMS. You have full control over how your app should be styled - using CSS.
>**Note**: We recommend styling your App to match the look and feel of the CMS. In the future, a design system will be provided by Agility that you can import into your app to assist with appropriate styling.
## Releasing New Versions
For contributors who are building new versions of this SDK, you will need to do the following to deploy your changes to `npm`.
1. Increase the `version` number in `package.json`
2. `npm run build` to bundle the JS.
3. `npm publish --access public` (requires authentication) to publish the new `@agility/app-sdk` package.
```
{
"compilerOptions": {
"allowJs": true,
"declaration": true,
"jsx": "react",
"target": "es5",
"outDir": "./dist/",
"lib": ["es2016", "dom"],
"esModuleInterop": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true
"target": "es5",
"module": "esnext",
"jsx": "react",
"sourceMap": true,
"outDir": "dist",
"strict": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationDir": "types",
"emitDeclarationOnly": true
},
"exclude": [
"node_modules",
"**/*stories",
"**/*types"
],
"include": [
"src/*.ts",
"src/*.tsx",
"src/*.js", "src/useAgilityAppSDK.ts" ]
}
"src/*.js",
"src/useAgilityAppSDK.ts"
]
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc