From 673cd75a3f45aac0db9e8788516ce249dcbfbfa0 Mon Sep 17 00:00:00 2001 From: Abhinav Jha Date: Wed, 18 Sep 2019 16:18:56 +0530 Subject: [PATCH] WIP: integrate with fetch pages and save pages APIs --- app/client/src/actions/pageActions.tsx | 17 +++- app/client/src/api/Api.tsx | 13 +++ app/client/src/api/ApiRequests.tsx | 7 +- app/client/src/api/ApiResponses.tsx | 30 +++++-- app/client/src/api/PageApi.tsx | 35 ++++++-- app/client/src/constants/ActionConstants.tsx | 86 +++++++++---------- app/client/src/constants/ApiConstants.tsx | 8 +- .../src/constants/ReduxActionConstants.tsx | 2 + .../normalizers/CanvasWidgetsNormalizer.tsx | 8 +- app/client/src/pages/Editor/index.tsx | 14 ++- app/client/src/pages/Editor/snapToGrid.ts | 5 -- .../entityReducers/canvasWidgetsReducer.tsx | 27 +++--- .../src/reducers/uiReducers/editorReducer.tsx | 4 + app/client/src/sagas/ActionSagas.tsx | 3 +- app/client/src/sagas/PageSagas.tsx | 86 +++++++++---------- app/client/src/sagas/utils.tsx | 13 +++ 16 files changed, 221 insertions(+), 137 deletions(-) delete mode 100644 app/client/src/pages/Editor/snapToGrid.ts create mode 100644 app/client/src/sagas/utils.tsx diff --git a/app/client/src/actions/pageActions.tsx b/app/client/src/actions/pageActions.tsx index 7521b4dc97..cfbc72bec3 100644 --- a/app/client/src/actions/pageActions.tsx +++ b/app/client/src/actions/pageActions.tsx @@ -1,4 +1,5 @@ import { FetchPageRequest } from "../api/PageApi"; +import { ResponseMeta } from "../api/ApiResponses"; import { RenderMode } from "../constants/WidgetConstants"; import { WidgetProps, @@ -13,6 +14,7 @@ import { SavePageErrorPayload, SavePageSuccessPayload, } from "../constants/ReduxActionConstants"; +import { ContainerWidgetProps } from "../widgets/ContainerWidget"; export const fetchPage = ( pageId: string, @@ -27,6 +29,13 @@ export const fetchPage = ( }; }; +export const fetchPageError = (payload: ResponseMeta) => { + console.log("FETCH PAGE ERROR", payload); + return { + type: ReduxActionTypes.FETCH_PAGE_ERROR, + }; +}; + export const addWidget = ( pageId: string, widget: WidgetProps, @@ -62,10 +71,14 @@ export const loadCanvasWidgets = ( }; }; -export const savePage = (payload: SavePagePayload) => { +export const savePage = ( + pageId: string, + layoutId: string, + dsl: ContainerWidgetProps, +): ReduxAction => { return { type: ReduxActionTypes.SAVE_PAGE_INIT, - payload, + payload: { pageId, layoutId, dsl }, }; }; diff --git a/app/client/src/api/Api.tsx b/app/client/src/api/Api.tsx index 3dc1825820..690287dab6 100644 --- a/app/client/src/api/Api.tsx +++ b/app/client/src/api/Api.tsx @@ -12,6 +12,12 @@ const axiosInstance = axios.create({ baseURL: BASE_URL, timeout: REQUEST_TIMEOUT_MS, headers: REQUEST_HEADERS, + withCredentials: true, + //TODO(abhinav): remove this. + auth: { + username: "api_user", + password: "8uA@;&mB:cnvN~{#", + }, }); axiosInstance.interceptors.response.use( @@ -54,6 +60,13 @@ class Api { ); } + static put(url: string, queryParams?: any, body?: any) { + return axiosInstance.put( + url + this.convertObjectToQueryParams(queryParams), + body, + ); + } + static convertObjectToQueryParams(object: any): string { if (!_.isNil(object)) { const paramArray: string[] = _.map(_.keys(object), key => { diff --git a/app/client/src/api/ApiRequests.tsx b/app/client/src/api/ApiRequests.tsx index 674fd1c1cf..9bda558de0 100644 --- a/app/client/src/api/ApiRequests.tsx +++ b/app/client/src/api/ApiRequests.tsx @@ -1,9 +1,10 @@ import { ContentType, DataType } from "../constants/ApiConstants"; export interface APIHeaders { - Accept: ContentType; - "Content-Type": ContentType; - dataType: DataType; + Accept?: ContentType; + "Content-Type"?: ContentType; + dataType?: DataType; + Origin?: string; } export interface APIRequest { diff --git a/app/client/src/api/ApiResponses.tsx b/app/client/src/api/ApiResponses.tsx index f7a10d2bab..7508c9ecba 100644 --- a/app/client/src/api/ApiResponses.tsx +++ b/app/client/src/api/ApiResponses.tsx @@ -1,10 +1,26 @@ -export type APIResponseCode = "SUCCESS" | "UNKNOWN"; +export type APIResponseError = { + code: number; + message: string; +}; -export interface ResponseMeta { - responseCode: APIResponseCode; - message?: string; -} +export type ResponseMeta = { + status: number; + success: boolean; + error?: APIResponseError; +}; -export interface ApiResponse { +export type ApiResponse = { responseMeta: ResponseMeta; -} + data: any; +}; + +// NO_RESOURCE_FOUND, 1000, "Unable to find {0} with id {1}" +// INVALID_PARAMTER, 4000, "Invalid parameter {0} provided in the input" +// PLUGIN_NOT_INSTALLED, 4001, "Plugin {0} not installed" +// MISSING_PLUGIN_ID, 4002, "Missing plugin id. Please input correct plugin id" +// MISSING_RESOURCE_ID, 4003, "Missing resource id. Please input correct resource id" +// MISSING_PAGE_ID, 4004, "Missing page id. Pleaes input correct page id" +// PAGE_DOES_NOT_EXIST_IN_ORG, 4006, "Page {0} does not belong to the current user {1} organization." +// UNAUTHORIZED_DOMAIN, 4001, "Invalid email domain provided. Please sign in with a valid work email ID" +// INTERNAL_SERVER_ERROR, 5000, "Internal server error while processing request" +// REPOSITORY_SAVE_FAILED, 5001, "Repository save failed." diff --git a/app/client/src/api/PageApi.tsx b/app/client/src/api/PageApi.tsx index c4b2876514..da0bd3162a 100644 --- a/app/client/src/api/PageApi.tsx +++ b/app/client/src/api/PageApi.tsx @@ -11,31 +11,50 @@ export interface FetchPageRequest { } export interface SavePageRequest { - pageWidget: ContainerWidgetProps; + dsl: ContainerWidgetProps; + layoutId: string; + pageId: string; } export interface PageLayout { + id: string; dsl: ContainerWidgetProps; - actions: PageAction[]; + actions?: PageAction[]; } -export interface FetchPageResponse extends ApiResponse { - layout: PageLayout; -} +export type FetchPageResponse = ApiResponse & { + data: { + id: string; + name: string; + applicationId: string; + layouts: Array; + }; +}; export interface SavePageResponse { pageId: string; } class PageApi extends Api { - static url = "/page"; + static url = "/pages"; + static getLayoutUpdateURL = (pageId: string, layoutId: string) => { + return `/layouts/${layoutId}/pages/${pageId}`; + }; static fetchPage(pageRequest: FetchPageRequest): Promise { - return Api.get(PageApi.url + "/" + pageRequest.pageId, pageRequest); + return Api.get(PageApi.url + "/" + pageRequest.pageId); } static savePage(savePageRequest: SavePageRequest): Promise { - return Api.post(PageApi.url, undefined, savePageRequest); + const body = { dsl: savePageRequest.dsl }; + return Api.put( + PageApi.getLayoutUpdateURL( + savePageRequest.pageId, + savePageRequest.layoutId, + ), + undefined, + body, + ); } } diff --git a/app/client/src/constants/ActionConstants.tsx b/app/client/src/constants/ActionConstants.tsx index c0fe51dd5c..80d4f0bbc8 100644 --- a/app/client/src/constants/ActionConstants.tsx +++ b/app/client/src/constants/ActionConstants.tsx @@ -1,75 +1,75 @@ import { AlertType, MessageIntent } from "../widgets/AlertWidget"; -export type EventType = - | "ON_CLICK" - | "ON_HOVER" - | "ON_TOGGLE" - | "ON_LOAD" - | "ON_TEXT_CHANGE" - | "ON_SUBMIT" - | "ON_CHECK_CHANGE" - | "ON_SELECT" - | "ON_DATE_SELECTED" - | "ON_DATE_RANGE_SELECTED" +export type EventType = + | "ON_CLICK" + | "ON_HOVER" + | "ON_TOGGLE" + | "ON_LOAD" + | "ON_TEXT_CHANGE" + | "ON_SUBMIT" + | "ON_CHECK_CHANGE" + | "ON_SELECT" + | "ON_DATE_SELECTED" + | "ON_DATE_RANGE_SELECTED"; -export type ActionType = +export type ActionType = | "API" - | "QUERY" - | "NAVIGATION" - | "ALERT" - | "JS_FUNCTION" - | "SET_VALUE" - | "DOWNLOAD" + | "QUERY" + | "NAVIGATION" + | "ALERT" + | "JS_FUNCTION" + | "SET_VALUE" + | "DOWNLOAD"; export interface ActionPayload { - actionType: ActionType - contextParams: Record + actionType: ActionType; + contextParams: Record; } export interface APIActionPayload extends ActionPayload { - apiId: string + apiId: string; } export interface QueryActionPayload extends ActionPayload { - queryId: string + queryId: string; } -export type NavigationType = "NEW_TAB" | "INLINE" +export type NavigationType = "NEW_TAB" | "INLINE"; export interface NavigateActionPayload extends ActionPayload { - pageUrl: string - navigationType: NavigationType + pageUrl: string; + navigationType: NavigationType; } export interface ShowAlertActionPayload extends ActionPayload { - header: string - message: string - alertType: AlertType - intent: MessageIntent + header: string; + message: string; + alertType: AlertType; + intent: MessageIntent; } export interface SetValueActionPayload extends ActionPayload { - header: string - message: string - alertType: AlertType - intent: MessageIntent + header: string; + message: string; + alertType: AlertType; + intent: MessageIntent; } export interface ExecuteJSActionPayload extends ActionPayload { - jsFunctionId: string + jsFunctionId: string; } -export type DownloadFiletype = "CSV" | "XLS" | "JSON" | "TXT" +export type DownloadFiletype = "CSV" | "XLS" | "JSON" | "TXT"; export interface DownloadDataActionPayload extends ActionPayload { - data: JSON - fileName: string - fileType: DownloadFiletype + data: JSON; + fileName: string; + fileType: DownloadFiletype; } export interface PageAction { - actionId: string - actionType: ActionType - actionName: string - dynamicBindings: string[] -} \ No newline at end of file + actionId: string; + actionType: ActionType; + actionName: string; + dynamicBindings: string[]; +} diff --git a/app/client/src/constants/ApiConstants.tsx b/app/client/src/constants/ApiConstants.tsx index 8e0e33b930..04924d604f 100644 --- a/app/client/src/constants/ApiConstants.tsx +++ b/app/client/src/constants/ApiConstants.tsx @@ -9,14 +9,12 @@ export type EncodingType = "gzip"; export const PROD_BASE_URL = "https://mobtools.com/api/"; export const MOCK_BASE_URL = "https://f78ff9dd-2c08-45f1-9bf9-8c670a1bb696.mock.pstmn.io"; -export const STAGE_BASE_URL = - "https://14157cb0-190f-4082-a791-886a8df05930.mock.pstmn.io"; -export const BASE_URL = MOCK_BASE_URL; -export const REQUEST_TIMEOUT_MS = 2000; +export const STAGE_BASE_URL = "https://appsmith-test.herokuapp.com/api/v1/"; +export const BASE_URL = STAGE_BASE_URL; +export const REQUEST_TIMEOUT_MS = 5000; export const REQUEST_HEADERS: APIHeaders = { Accept: "application/json", "Content-Type": "application/json", - dataType: "json", }; export interface APIException { diff --git a/app/client/src/constants/ReduxActionConstants.tsx b/app/client/src/constants/ReduxActionConstants.tsx index 57d4adfb44..4976463c80 100644 --- a/app/client/src/constants/ReduxActionConstants.tsx +++ b/app/client/src/constants/ReduxActionConstants.tsx @@ -26,6 +26,7 @@ export const ReduxActionTypes = { SAVE_PAGE_INIT: "SAVE_PAGE_INIT", SAVE_PAGE_SUCCESS: "SAVE_PAGE_SUCCESS", SAVE_PAGE_ERROR: "SAVE_PAGE_ERROR", + FETCH_PAGE_ERROR: "FETCH_PAGE_ERROR", }; export type ReduxActionType = (typeof ReduxActionTypes)[keyof typeof ReduxActionTypes]; @@ -38,6 +39,7 @@ export interface ReduxAction { export interface LoadCanvasWidgetsPayload { pageWidgetId: string; widgets: { [widgetId: string]: WidgetProps }; + layoutId: string; } export interface LoadWidgetConfigPayload { diff --git a/app/client/src/normalizers/CanvasWidgetsNormalizer.tsx b/app/client/src/normalizers/CanvasWidgetsNormalizer.tsx index 12a3a5fc35..6e7071a5f6 100644 --- a/app/client/src/normalizers/CanvasWidgetsNormalizer.tsx +++ b/app/client/src/normalizers/CanvasWidgetsNormalizer.tsx @@ -1,5 +1,5 @@ import { normalize, schema, denormalize } from "normalizr"; -import { FetchPageResponse } from "../api/PageApi"; +import { WidgetProps } from "../widgets/BaseWidget"; import { ContainerWidgetProps } from "../widgets/ContainerWidget"; export const widgetSchema = new schema.Entity( @@ -11,15 +11,15 @@ widgetSchema.define({ children: [widgetSchema] }); class CanvasWidgetsNormalizer { static normalize( - pageResponse: FetchPageResponse, + dsl: ContainerWidgetProps, ): { entities: any; result: any } { - return normalize(pageResponse.layout.dsl, widgetSchema); + return normalize(dsl, widgetSchema); } static denormalize( pageWidgetId: string, entities: any, - ): ContainerWidgetProps { + ): ContainerWidgetProps { return denormalize(pageWidgetId, widgetSchema, entities); } } diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index 723e02d202..f0ec6d0a2d 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -13,7 +13,7 @@ import WidgetCardsPane from "./WidgetCardsPane"; import EditorHeader from "./EditorHeader"; import CanvasWidgetsNormalizer from "../../normalizers/CanvasWidgetsNormalizer"; import { ContainerWidgetProps } from "../../widgets/ContainerWidget"; -import { fetchPage, updateWidget } from "../../actions/pageActions"; +import { fetchPage, updateWidget, savePage } from "../../actions/pageActions"; import { RenderModes } from "../../constants/WidgetConstants"; import EditorDragLayer from "./EditorDragLayer"; @@ -51,12 +51,15 @@ type EditorProps = { fetchCanvasWidgets: Function; cards: { [id: string]: WidgetCardProps[] } | any; updateWidgetProperty: Function; + savePageLayout: Function; page: string; + currentPageId: string; + currentLayoutId: string; }; class Editor extends Component { componentDidMount() { - this.props.fetchCanvasWidgets("1"); + this.props.fetchCanvasWidgets(this.props.currentPageId); } public render() { @@ -89,6 +92,8 @@ const mapStateToProps = (state: AppState): EditorReduxState => { cards: state.ui.widgetCardsPane.cards, layout, pageWidgetId: state.ui.editor.pageWidgetId, + currentPageId: state.ui.editor.currentPageId, + currentLayoutId: state.ui.editor.currentLayoutId, }; }; @@ -101,6 +106,11 @@ const mapDispatchToProps = (dispatch: any) => { widgetProps: WidgetProps, payload: any, ) => dispatch(updateWidget(propertyType, widgetProps, payload)), + savePageLayout: ( + pageId: string, + layoutId: string, + dsl: ContainerWidgetProps, + ) => dispatch(savePage(pageId, layoutId, dsl)), }; }; diff --git a/app/client/src/pages/Editor/snapToGrid.ts b/app/client/src/pages/Editor/snapToGrid.ts deleted file mode 100644 index 1c0a3ffa3d..0000000000 --- a/app/client/src/pages/Editor/snapToGrid.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default function snapToGrid(cellSize: number, x: number, y: number) { - const snappedX = Math.round(x / cellSize) * cellSize - const snappedY = Math.round(y / cellSize) * cellSize - return [snappedX, snappedY] -} diff --git a/app/client/src/reducers/entityReducers/canvasWidgetsReducer.tsx b/app/client/src/reducers/entityReducers/canvasWidgetsReducer.tsx index e259bd54db..f58109cf09 100644 --- a/app/client/src/reducers/entityReducers/canvasWidgetsReducer.tsx +++ b/app/client/src/reducers/entityReducers/canvasWidgetsReducer.tsx @@ -5,7 +5,6 @@ import { ReduxAction, } from "../../constants/ReduxActionConstants"; import { WidgetProps } from "../../widgets/BaseWidget"; -import CanvasWidgetsNormalizer from "../../normalizers/CanvasWidgetsNormalizer"; const initialState: CanvasWidgetsReduxState = {}; @@ -24,18 +23,20 @@ const canvasWidgetsReducer = createReducer(initialState, { state: CanvasWidgetsReduxState, action: ReduxAction<{ pageId: string; widget: WidgetProps }>, ) => { - const widget = action.payload.widget; - const widgetTree = CanvasWidgetsNormalizer.denormalize("0", { - canvasWidgets: state, - }); - const children = widgetTree.children || []; - children.push(widget); - widgetTree.children = children; - const newState = CanvasWidgetsNormalizer.normalize({ - responseMeta: { responseCode: "SUCCESS" }, - layout: { dsl: widgetTree, actions: [] }, - }).entities; - return newState.canvasWidgets; + // const widget = action.payload.widget; + // const widgetTree = CanvasWidgetsNormalizer.denormalize("0", { + // canvasWidgets: state, + // }); + // const children = widgetTree.children || []; + // children.push(widget); + // widgetTree.children = children; + // const newState = CanvasWidgetsNormalizer.normalize({ + // responseMeta: { responseCode: "SUCCESS" }, + // layout: { dsl: widgetTree, actions: [] }, + // }).entities; + // return newState.canvasWidgets; + console.log(action.payload.widget); + return state; }, }); diff --git a/app/client/src/reducers/uiReducers/editorReducer.tsx b/app/client/src/reducers/uiReducers/editorReducer.tsx index 094013ea23..fd0db2ae1d 100644 --- a/app/client/src/reducers/uiReducers/editorReducer.tsx +++ b/app/client/src/reducers/uiReducers/editorReducer.tsx @@ -10,6 +10,8 @@ import { ContainerWidgetProps } from "../../widgets/ContainerWidget"; const initialState: EditorReduxState = { pageWidgetId: "0", + currentPageId: "5d807e76795dc6000482bc76", + currentLayoutId: "5d807e76795dc6000482bc75", }; const editorReducer = createReducer(initialState, { @@ -36,6 +38,8 @@ export interface EditorReduxState { [id: string]: WidgetCardProps[]; }; pageWidgetId: string; + currentPageId: string; + currentLayoutId: string; } export default editorReducer; diff --git a/app/client/src/sagas/ActionSagas.tsx b/app/client/src/sagas/ActionSagas.tsx index 2f706d2b29..9d271e1824 100644 --- a/app/client/src/sagas/ActionSagas.tsx +++ b/app/client/src/sagas/ActionSagas.tsx @@ -15,6 +15,7 @@ import ActionAPI, { ActionCreatedResponse } from "../api/ActionAPI"; import { AppState } from "../reducers"; import { JSONPath } from "jsonpath-plus"; import _ from "lodash"; +import { extractCurrentDSL } from "./utils"; const getDataTree = (state: AppState) => { return state.entities; @@ -82,7 +83,7 @@ export function* executeAction( ); if (pageRequest.renderMode === RenderModes.CANVAS) { const normalizedResponse = CanvasWidgetsNormalizer.normalize( - pageResponse, + extractCurrentDSL(pageResponse), ); const payload = { pageWidgetId: normalizedResponse.result, diff --git a/app/client/src/sagas/PageSagas.tsx b/app/client/src/sagas/PageSagas.tsx index e3b1208281..87143da314 100644 --- a/app/client/src/sagas/PageSagas.tsx +++ b/app/client/src/sagas/PageSagas.tsx @@ -8,6 +8,7 @@ import { loadCanvasWidgets, savePageError, savePageSuccess, + fetchPageError, } from "../actions/pageActions"; import PageApi, { FetchPageResponse, @@ -16,64 +17,62 @@ import PageApi, { SavePageRequest, } from "../api/PageApi"; import { call, put, takeLatest, all } from "redux-saga/effects"; -import { RenderModes } from "../constants/WidgetConstants"; +import { extractCurrentDSL } from "./utils"; export function* fetchPage(pageRequestAction: ReduxAction) { const pageRequest = pageRequestAction.payload; try { - // const pageResponse: PageResponse = yield call( - // PageApi.fetchPage, - // pageRequest, - // ); - if (pageRequest.renderMode === RenderModes.CANVAS) { - const pageResponse = JSON.parse(`{ - "responseMeta": {}, - "layout": { - "dsl": { - "widgetId": "0", - "type": "CONTAINER_WIDGET", - "snapColumns": 16, - "snapRows": 100, - "topRow": 0, - "bottomRow": 2000, - "leftColumn": 0, - "rightColumn": 1000, - "parentColumnSpace": 1, - "parentRowSpace": 1, - "backgroundColor": "#ffffff", - "renderMode": "CANVAS", - "children": [ - { - "widgetId": "1", - "type": "CONTAINER_WIDGET", - "snapColumns": 10, - "snapRows": 10, - "topRow": 1, - "bottomRow": 20, - "leftColumn": 1, - "rightColumn": 16, - "backgroundColor": "#000000", - "renderMode": "CANVAS", - "children": [] - } - ] - } - } - }`); + const fetchPageResponse: FetchPageResponse = yield call( + PageApi.fetchPage, + pageRequest, + ); + if (fetchPageResponse.responseMeta.success) { const normalizedResponse = CanvasWidgetsNormalizer.normalize( - pageResponse, + extractCurrentDSL(fetchPageResponse), ); const canvasWidgetsPayload: LoadCanvasWidgetsPayload = { pageWidgetId: normalizedResponse.result, widgets: normalizedResponse.entities.canvasWidgets, + layoutId: fetchPageResponse.data.layouts[0].id, }; - yield put(loadCanvasWidgets(canvasWidgetsPayload)); yield put({ type: ReduxActionTypes.LOAD_CANVAS_ACTIONS, - payload: pageResponse.layout.actions, + payload: fetchPageResponse.data.layouts[0].actions, // TODO: Refactor }); + } else { + yield put(fetchPageError(fetchPageResponse.responseMeta)); } + // const fetchPageResponse = JSON.parse(`{ + // "responseMeta": { + // "success": true, + // "code": 200 + // }, + // "data": { + // "id": "5d807e76795dc6000482bc76", + // "applicationId": "5d807e45795dc6000482bc74", + // "layouts": [ + // { + // "id": "5d807e76795dc6000482bc75", + // "dsl": { + // "widgetId": "0", + // "type": "CONTAINER_WIDGET", + // "snapColumns": 16, + // "snapRows": 100, + // "topRow": 0, + // "bottomRow": 2000, + // "leftColumn": 0, + // "rightColumn": 1000, + // "parentColumnSpace": 1, + // "parentRowSpace": 1, + // "backgroundColor": "#ffffff", + // "renderMode": "CANVAS", + // "children": [] + // } + // } + // ] + // } + // }`); } catch (err) { console.log(err); //TODO(abhinav): REFACTOR THIS @@ -82,7 +81,6 @@ export function* fetchPage(pageRequestAction: ReduxAction) { export function* savePage(savePageAction: ReduxAction) { const savePageRequest = savePageAction.payload; - try { const savePageResponse: SavePageResponse = yield call( PageApi.savePage, diff --git a/app/client/src/sagas/utils.tsx b/app/client/src/sagas/utils.tsx new file mode 100644 index 0000000000..e9ea2c0c5f --- /dev/null +++ b/app/client/src/sagas/utils.tsx @@ -0,0 +1,13 @@ +import { FetchPageResponse } from "../api/PageApi"; +import { ContainerWidgetProps } from "../widgets/ContainerWidget"; +import { WidgetProps } from "../widgets/BaseWidget"; + +export const extractCurrentDSL = ( + fetchPageResponse: FetchPageResponse, +): ContainerWidgetProps => { + return fetchPageResponse.data.layouts[0].dsl; +}; + +export default { + extractCurrentDSL, +};