Skip to content

Commit

Permalink
Merge pull request #62 from contentstack/CS-26933/default-modal-config
Browse files Browse the repository at this point in the history
feat: add default modal configuration
  • Loading branch information
Deepak-Kharah authored Apr 11, 2023
2 parents 5a17e96 + d054c9b commit 1aec861
Show file tree
Hide file tree
Showing 16 changed files with 157 additions and 124 deletions.
57 changes: 57 additions & 0 deletions __test__/extension.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Extension from "../src/extension";
import { IAppConfigInitData } from "../src/types";

jest.mock("post-robot", () => ({
sendToParent: jest.fn(),
on: jest.fn(),
}));

const initData: IAppConfigInitData = {
data: {
type: "APP_CONFIG_WIDGET",
app_id: "app_id",
installation_uid: "installation_uid",
extension_uid: "extension_uid",
stack: {
created_at: "created_at",
updated_at: "updated_at",
uid: "uid",
org_uid: "org_uid",
api_key: "api_key",
master_locale: "master_locale",
is_asset_download_public: true,
owner_uid: "owner_uid",
user_uids: ["user_uids"],
settings: {},
name: "name",
},
user: {},
currentBranch: "currentBranch",
},
};

describe("Main extension", () => {

afterEach(() => {
window["postRobot"] = undefined;
window["iframeRef"] = undefined;
})

it("should have modal property", () => {
const extension = new Extension(initData);
expect(extension.modal).toBeDefined();
})

describe("Properties in the window object", () => {
it("should have postRobot property", () => {
expect(window["postRobot"]).toBeUndefined();
new Extension(initData);
expect(window["postRobot"]).toBeDefined();

Object.prototype.hasOwnProperty.call(
window["postRobot"],
"sendToParent"
);
});
});
});
48 changes: 48 additions & 0 deletions __test__/modal.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Modal from "../src/modal";

describe("Modal module", () => {
const bodyChildInnerText = "body-child";
const divElementInnerText = "separate-div";

const bodyChild = document.createElement("div");
bodyChild.innerText = bodyChildInnerText;
document.body.appendChild(bodyChild);

const divElement = document.createElement("div");
divElement.innerText = divElementInnerText;
document.body.appendChild(divElement);

afterEach(() => {
window["iframeRef"] = undefined;
});

it("should add first child of the body to iframeRef if the user has not provided one", () => {
expect(window["iframeRef"]).toBeUndefined();

new Modal();
expect(window["iframeRef"]).toBeDefined();
expect(window["iframeRef"].tagName).toBe(bodyChild.tagName);
expect(window["iframeRef"].innerText).toBe(bodyChildInnerText);
});

it("should not add anything to iframeRef if it already exists", () => {
window["iframeRef"] = divElement;

new Modal();
const iframeRef = window["iframeRef"];

expect(iframeRef).toBeDefined();
expect(iframeRef.tagName).toBe(divElement.tagName);
expect(iframeRef.innerText).toBe(divElementInnerText);
});

it("should set iframeRef to the element provided by the user", () => {
const modal = new Modal();
modal.setBackgroundElement(divElement);
const iframeRef = window["iframeRef"];

expect(iframeRef).toBeDefined();
expect(iframeRef.tagName).toBe(divElement.tagName);
expect(iframeRef.innerText).toBe(divElementInnerText);
});
});
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

18 changes: 0 additions & 18 deletions dist/src/entryFieldLocation/entry.d.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1 @@
import Entry from "../entry";
import { IEntryFieldLocationInitData } from "../types";
import { IGetTagsOptions } from "../types/entry.types";
declare class EntryFieldLocationEntry extends Entry {
constructor(initializationData: IEntryFieldLocationInitData, connection: any, emitter: EventEmitter);
/**
* Returns the value of the tags associated with the entry.
* @returns {string[]} Returns an array of tags associated with the entry.
*/
getTags(options?: IGetTagsOptions): Array<string>;
/**
* Sets the tags on the entry.
* @param tags tags to be set on the entry
* @returns {string[]} Returns an array of tags associated with the entry.
*/
setTags(tags: Array<string>): Promise<Array<string>>;
}
export default EntryFieldLocationEntry;
//# sourceMappingURL=entry.d.ts.map
2 changes: 1 addition & 1 deletion dist/src/entryFieldLocation/entry.d.ts.map

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

39 changes: 0 additions & 39 deletions dist/src/entryFieldLocation/field.d.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1 @@
import EventEmitter from "wolfy87-eventemitter";
import { IFieldInitData, IEntryFieldLocationInitData } from "../types";
/** Class representing a field from Contentstack UI. Only available for Custom Field extension */
declare class EntryFieldLocationField {
/**
* @hideconstructor
*/
uid: string;
data_type: string;
schema: {
[key: string]: any;
};
_emitter: EventEmitter;
_data: {
[key: string]: any;
};
_resolvedData: {
[key: string]: any;
};
_self: any;
_connection: any;
constructor(fieldDataObject: IFieldInitData | IEntryFieldLocationInitData, connection: any, emitter: EventEmitter);
/**
* Sets the data for the current field.
* @param {Object|string|number} data Data to be set on the field
* @return {external:Promise} A promise object which is resolved when data is set for a field. Note: The data set by this function will only be saved when user saves the entry.
*/
setData(data: any): Promise<EntryFieldLocationField>;
/**
* Gets the data of the current field
* @param {Object} options Options object for get Data method.
* @param {boolean} options.resolved If the resolved parameter is set to true for the File field, then the method will return a resolved asset object along with all the field metadata, e.g. 'field.getData({resolved:true})'.
* @return {Object|string|number} Returns the field data.
*/
getData({ resolved }?: {
resolved?: boolean;
}): any;
}
export default EntryFieldLocationField;
//# sourceMappingURL=field.d.ts.map
2 changes: 1 addition & 1 deletion dist/src/entryFieldLocation/field.d.ts.map

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

42 changes: 0 additions & 42 deletions dist/src/entryFieldLocation/frame.d.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1 @@
import EventEmitter from "wolfy87-eventemitter";
/**
* Class representing an iframe window from Contentstack UI. Not available for Custom Widgets.
*/
declare class EntryFieldLocationFrame {
/**
* @hideconstructor
*/
_connection: any;
_autoResizingEnabled: boolean;
_emitter: EventEmitter;
_height?: number;
_width?: number;
private observer;
constructor(connection: any, emitter: EventEmitter);
/**
* This method updates the extension height and width on Contentstack UI.
* If the value is not passed, it will update the height and width of the
* extension with the current height and width of the extension.
* @param {string|number} height Desired height of the iframe window
*/
updateDimension(dimension?: {
height?: number;
width?: number;
}): Promise<void>;
/**
* This method enables auto resizing of the extension height.
* @return {EntryFieldLocationFrame}.
*/
enableAutoResizing(): EntryFieldLocationFrame;
/**
* This method disables auto resizing of the extension height.
* @return {EntryFieldLocationFrame}.
*/
disableAutoResizing(): EntryFieldLocationFrame;
/**
* It closes the app modal.
* @returns {Promise<void>}
*/
closeModal(): Promise<void>;
}
export default EntryFieldLocationFrame;
//# sourceMappingURL=frame.d.ts.map
2 changes: 1 addition & 1 deletion dist/src/entryFieldLocation/frame.d.ts.map

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

10 changes: 6 additions & 4 deletions dist/src/extension.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import AssetSidebarWidget from "./AssetSidebarWidget";
import { IRTEPluginInitializer } from "./RTE/types";
import Metadata from "./metadata";
import Modal from "./modal";
import Stack from "./stack";
import Store from "./store";
import Metadata from "./metadata";
import { IAppConfigInitData, IAppConfigWidget, IAssetSidebarInitData, ICustomField, IDashboardInitData, IDashboardWidget, IFieldInitData, IFieldModifierLocation, IFieldModifierLocationInitData, ILocation, IPageWidget, IRTEInitData, ISidebarInitData, ISidebarWidget, IUser, IFullPageLocationInitData, IFullPageLocation, IEntryFieldLocation, IEntryFieldLocationInitData } from "./types";
import { IRTEPluginInitializer } from "./RTE/types";
import AssetSidebarWidget from "./AssetSidebarWidget";
import { IAppConfigInitData, IAppConfigWidget, IAssetSidebarInitData, ICustomField, IDashboardInitData, IDashboardWidget, IEntryFieldLocation, IEntryFieldLocationInitData, IFieldInitData, IFieldModifierLocation, IFieldModifierLocationInitData, IFullPageLocation, IFullPageLocationInitData, ILocation, IPageWidget, IRTEInitData, ISidebarInitData, ISidebarWidget, IUser } from "./types";
/** Class representing an extension from Contentstack App Framework SDK. */
declare class Extension {
/**
Expand All @@ -19,6 +20,7 @@ declare class Extension {
store: Store;
metadata: Metadata;
locationUID: string;
modal: Modal;
location: {
DashboardWidget: IDashboardWidget | null;
SidebarWidget: ISidebarWidget | null;
Expand Down
2 changes: 1 addition & 1 deletion dist/src/extension.d.ts.map

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

6 changes: 6 additions & 0 deletions dist/src/modal.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
declare class Modal {
constructor();
setBackgroundElement(element: HTMLElement): void;
}
export default Modal;
//# sourceMappingURL=modal.d.ts.map
1 change: 1 addition & 0 deletions dist/src/modal.d.ts.map

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

36 changes: 21 additions & 15 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
import postRobot from "post-robot";
import EventEmitter from "wolfy87-eventemitter";

import AssetSidebarWidget from "./AssetSidebarWidget";
import { IRTEPluginInitializer } from "./RTE/types";
import { AppConfig } from "./appConfig";
import Entry from "./entry";
import Field from "./field";
import Window from "./window";
import FieldModifierLocationEntry from "./fieldModifierLocation/entry";
import FieldModifierLocationField from "./fieldModifierLocation/field";
import FieldModifierLocationFrame from "./fieldModifierLocation/frame";
import Metadata from "./metadata";
import Modal from "./modal";
import Stack from "./stack";
import Entry from "./entry";
import Store from "./store";
import Metadata from "./metadata";
import EventEmitter from "wolfy87-eventemitter";
import {
IAppConfigInitData,
IAppConfigWidget,
IAssetSidebarInitData,
ICustomField,
IDashboardInitData,
IDashboardWidget,
IEntryFieldLocation,
IEntryFieldLocationInitData,
IFieldInitData,
IFieldModifierLocation,
IFieldModifierLocationInitData,
IFullPageLocation,
IFullPageLocationInitData,
ILocation,
IPageWidget,
IRTEInitData,
ISidebarInitData,
ISidebarWidget,
IUser,
IFullPageLocationInitData,
IFullPageLocation,
IEntryFieldLocation,
IEntryFieldLocationInitData,
} from "./types";
import { IRTEPluginInitializer } from "./RTE/types";
import { onData, onError } from "./utils/utils";
import { AppConfig } from "./appConfig";
import AssetSidebarWidget from "./AssetSidebarWidget";
import { AnyObject } from "./types/common.types";
import FieldModifierLocationField from "./fieldModifierLocation/field";
import FieldModifierLocationFrame from "./fieldModifierLocation/frame";
import FieldModifierLocationEntry from "./fieldModifierLocation/entry";
import { onData, onError } from "./utils/utils";
import Window from "./window";

const emitter = new EventEmitter();

Expand All @@ -55,6 +57,7 @@ class Extension {
store: Store;
metadata: Metadata;
locationUID: string;
modal: Modal;

location: {
DashboardWidget: IDashboardWidget | null;
Expand Down Expand Up @@ -145,6 +148,9 @@ class Extension {
FieldModifierLocation: null,
};

window["postRobot"] = postRobot;

this.modal = new Modal();
const stack = new Stack(initializationData.data.stack, postRobot, {
currentBranch: initializationData.data.currentBranch,
});
Expand Down
12 changes: 12 additions & 0 deletions src/modal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Modal {
constructor() {
if (!Object.prototype.hasOwnProperty.call(window, "iframeRef")) {
window["iframeRef"] = document?.body?.children[0];
}
}
setBackgroundElement(element: HTMLElement) {
window["iframeRef"] = element;
}
}

export default Modal;

0 comments on commit 1aec861

Please sign in to comment.