Name
sn_ace.ACEAppBuilderUtil
Description
No description available
Script
var ACEAppBuilderUtil = Class.create();
ACEAppBuilderUtil.prototype = {
initialize: function() {
this.CONSTANTS = new ACEAppBuilderMetaData();
this.TABLE = this.CONSTANTS.TABLES;
this.UXF_TABLE = this.CONSTANTS.UXF_TABLES;
this.GLOBAL = new global.ACEAppBuilderGlobalScopedUtil();
this.CREATE_DEMO_DATA = false;
this.demoUtils = new ACEDemoDataUtils();
this.AIS = this.CONSTANTS.AIS;
this.ALL_CONTENT_BLOCK_TYPES = this.getAllContentBlockTypes(this.TABLE.TYPE);
this.EXPERIENCE_ID = null;
this.VIRTUAL_GR = null;
this.gr_counter = 0;
this.CAN_READ = this.hasReadAccess();
this.DEFAULT_FETCH_MODE = 'dfs';
this.SUPPORTED_FETCH_MODES = ['dfs', 'bfs'];
},
_getVirtualGrInstance: function(cbId) {
if (!cbId) return null;
var gr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
if (gr.get(cbId)) {
return gr;
}
return null;
},
_cachedScriptEvaluator: function(grInstance, scriptField, scriptValue, context) {
try {
if (!grInstance || !scriptValue) return context ? context : true;
grInstance.setValue(scriptField, scriptValue);
var evaluator = new GlideScopedEvaluator();
if (context) {
evaluator.putVariable('context', context);
evaluator.evaluateScript(grInstance, scriptField, null);
} else {
evaluator.putVariable('answer', null);
evaluator.putVariable('current', grInstance);
evaluator.evaluateScript(grInstance, scriptField, null);
return evaluator.getVariable('answer');
}
} catch (e) {
gs.log('ACEAppBuilder: Exception executing script of cached content block, ' + e);
}
},
_scriptEvaluator: function(grInstance, context, fieldName, pageParams) {
try {
if (!fieldName || !grInstance.getValue(fieldName))
return context;
var evaluator = new GlideScopedEvaluator();
evaluator.putVariable('context', context);
evaluator.putVariable('pageParams', pageParams);
evaluator.evaluateScript(grInstance, fieldName, null);
} catch (e) {
gs.error('ACEAppBuilder: Exception executing script of content block, ' + e.toString());
}
},
_evaluatePostScript: function(grInstance, context, pageParams) {
this._scriptEvaluator(grInstance, context, 'post_script', pageParams);
},
_evaluateLazyScript: function(grInstance, context, pageParams) {
this._scriptEvaluator(grInstance, context, 'lazy_script');
},
_visibilityEvaluator: function(grInstance, pageParams) {
try {
if (!grInstance.getValue('visibility'))
return true;
var evaluator = new GlideScopedEvaluator();
evaluator.putVariable('answer', null);
evaluator.putVariable('current', grInstance);
evaluator.putVariable('pageParams', pageParams);
evaluator.evaluateScript(grInstance, 'visibility', null);
return evaluator.getVariable('answer');
} catch (e) {
gs.error('ACEAppBuilder: Exception executing script of content block, ' + e.toString());
return false;
}
},
_getValuePairsFromClonedRecord: function(table, sysId, fields) {
try {
if (!table || !sysId || !this.CAN_READ) return {};
var valuePairs = {};
var gr = new GlideRecord(table);
if (gr.get(sysId)) {
fields.forEach(function(field) {
valuePairs[field] = gr.getValue(field);
});
return valuePairs;
}
return {};
} catch (e) {
return {};
}
},
_grRecordCreator: function(table, valuePairs, cloneInfo) {
try {
var clonedValuePairs = {},
field;
if (cloneInfo && cloneInfo.sys_id && Array.isArray(cloneInfo.fields) && cloneInfo.fields.length > 0) {
clonedValuePairs = this._getValuePairsFromClonedRecord(table, cloneInfo.sys_id, cloneInfo.fields);
}
var gr = new GlideRecord(table);
gr.initialize();
gr.sys_scope = gs.getCurrentApplicationId();
for (field in clonedValuePairs) {
gr[field] = clonedValuePairs[field];
}
for (field in valuePairs) {
if (field == 'props_details' && table == this.TABLE.CONTENT_BLOCK) {
for (var i in valuePairs.props_details) {
gr.variable[i] = valuePairs.props_details[i];
}
} else
gr[field] = valuePairs[field];
}
return gr.insert();
} catch (e) {
gs.error("ACEAppBuilderUtil: Error in Glide Record Creation: " + e.toString());
return null;
}
},
_updateMacroponentProp: function(macroponentId, field, element, inputValueProp, newValue) {
try {
var _self = this;
var gr = new GlideRecord(this.UXF_TABLE.MACROPONENT);
if (gr.get(macroponentId)) {
var fieldData = gr.getValue(field);
fieldData = JSON.parse(fieldData);
if (Array.isArray(fieldData)) {
for (var i = 0; i < fieldData.length; i++) {
var dataBroker = fieldData[i];
if (dataBroker.elementId == element) {
dataBroker.inputValues[inputValueProp].value = newValue.toString();
var input = {};
input[field] = JSON.stringify(fieldData, null, 1);
_self.GLOBAL.updateRecord(_self.UXF_TABLE.MACROPONENT, gr.getUniqueValue(), input);
}
}
}
return true;
}
} catch (e) {
return null;
}
},
createPage: function(appConfigId, name, aceAppSysId, template, pageId) {
var screenTypeId = this.GLOBAL._grRecordCreator(this.UXF_TABLE.SCREEN_TYPE, {
'name': name
}, {
'sys_id': this._getConstantsForPage(template).SCREEN_TYPE,
'fields': this.CONSTANTS.CLONE_FIELDS.SCREEN_TYPE
});
var macroponentId = this._createMacroponent(name, template);
var screenId = this._createScreen(macroponentId, appConfigId, screenTypeId, name, template);
var appRouteId = this._createRoute(appConfigId, screenTypeId, name, template);
// TODO: Have segregation between methods that create UXF artifacts and ACE artifacts
if (pageId) {
if (!this._updateMacroponentProp(macroponentId, 'data', this.CONSTANTS.BASE_UXF_RECORDS.SECTIONS_DATA_BROKER_NAME, 'page_route', pageId)) {
gs.addErrorMessage(gs.getMessage('Please update the macroponent prop value via UIB'));
}
// FIXME: Remove references to hardcoded template names
if (template != 'Home')
this._createContentBlocks(pageId, this.CONSTANTS.DEFAULT_CONTENT_BLOCKS);
}
return {
route: appRouteId,
screenType: screenTypeId,
screen: screenId,
macroponent: macroponentId
};
},
_createRoute: function(appConfig, screenType, name, template) {
var cloneInfo = {
'sys_id': this._getConstantsForPage(template).ROUTE,
'fields': this.CONSTANTS.CLONE_FIELDS.APP_ROUTE
};
var payload = {
'name': name,
'app_config': appConfig,
'screen_type': screenType,
'route_type': name.toLowerCase()
};
return this.GLOBAL._grRecordCreator(this.UXF_TABLE.APP_ROUTE, payload, cloneInfo);
},
_cloneClientScripts: function(baseMacroponentId, newMacroponentId) {
var clientScriptMaps = [];
try {
var _self = this;
var gr = new GlideRecord(_self.UXF_TABLE.CLIENT_SCRIPT);
gr.addQuery('macroponent', baseMacroponentId);
gr.query();
while (gr.next()) {
var newClientScriptId = this.GLOBAL._grRecordCreator(_self.UXF_TABLE.CLIENT_SCRIPT, {
'macroponent': newMacroponentId,
'name': gr.getValue('name'),
'type': gr.getValue('type'),
'script': gr.getValue('script'),
});
clientScriptMaps.push({
'findId': gr.getValue('sys_id'),
'replaceWithId': newClientScriptId
});
}
return clientScriptMaps;
} catch (e) {
return clientScriptMaps;
}
},
_replaceAll: function(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
},
_createMacroponent: function(name, template) {
var _self = this;
var cloneInfo = {
'sys_id': _self._getConstantsForPage(template).MACROPONENT,
'fields': _self.CONSTANTS.CLONE_FIELDS.MACROPONENT
};
var macroponentId = this.GLOBAL._grRecordCreator(this.UXF_TABLE.MACROPONENT, {
'name': name
}, cloneInfo);
var clientScriptMaps = _self._cloneClientScripts(this._getConstantsForPage(template).MACROPONENT, macroponentId);
//postCleanUp
var gr = new GlideRecord(_self.UXF_TABLE.MACROPONENT);
if (gr.get(macroponentId)) {
var postUpdateComposition = {
'composition': gr.getValue('composition'),
'data': gr.getValue('data'),
'state_properties': gr.getValue('state_properties'),
'internal_event_mappings': gr.getValue('internal_event_mappings'),
};
clientScriptMaps.forEach(function(clientScriptMap) {
postUpdateComposition.composition = _self._replaceAll(postUpdateComposition.composition, clientScriptMap.findId, clientScriptMap.replaceWithId);
postUpdateComposition.data = _self._replaceAll(postUpdateComposition.data, clientScriptMap.findId, clientScriptMap.replaceWithId);
postUpdateComposition.state_properties = _self._replaceAll(postUpdateComposition.state_properties, clientScriptMap.findId, clientScriptMap.replaceWithId);
postUpdateComposition.internal_event_mappings = _self._replaceAll(postUpdateComposition.internal_event_mappings, clientScriptMap.findId, clientScriptMap.replaceWithId);
});
//gr.update();
_self.GLOBAL.updateRecord(_self.UXF_TABLE.MACROPONENT, macroponentId, postUpdateComposition);
}
return macroponentId;
},
_createScreen: function(macroponent, appConfig, screenType, name, template) {
var cloneInfo = {
'sys_id': this._getConstantsForPage(template).SCREEN,
'fields': this.CONSTANTS.CLONE_FIELDS.UX_SCREEN
};
var payload = {
'name': name,
'macroponent': macroponent,
'app_config': appConfig,
'screen_type': screenType
};
return this.GLOBAL._grRecordCreator(this.UXF_TABLE.SCREEN, payload, cloneInfo);
},
_getConstantsForPage: function(name) {
switch (name) {
case 'Home':
return this.CONSTANTS.BASE_UXF_RECORDS.HOME_PAGE;
case 'Settings':
return this.CONSTANTS.BASE_UXF_RECORDS.SETTINGS_PAGE;
case 'Search':
return this.CONSTANTS.BASE_UXF_RECORDS.SEARCH_PAGE;
case 'List':
return this.CONSTANTS.BASE_UXF_RECORDS.LIST_PAGE;
case 'Record':
return this.CONSTANTS.BASE_UXF_RECORDS.RECORD_PAGE;
case 'Content Block':
return this.CONSTANTS.BASE_UXF_RECORDS.CONTENT_BLOCK;
default:
return this.CONSTANTS.BASE_UXF_RECORDS.BLANK_PAGE;
}
},
_createContentBlocks: function(pageId, contentBlocks) {
var _self = this;
function createContentBlock(pageId, block, parent) {
try {
var payload = JSON.parse(JSON.stringify(block));
payload.type = block.type.id;
payload.parent = parent;
payload.document_table = _self.TABLE.PAGE;
payload.document_id = pageId;
var blockId = _self._grRecordCreator(_self.TABLE.CONTENT_BLOCK, payload);
block.children && block.children.forEach(function(child) {
createContentBlock(pageId, child, blockId);
});
} catch (e) {
gs.error('ACEAppBuilderUtil: error creating content blocks: ' + e.toString());
}
}
contentBlocks.forEach(function(block) {
createContentBlock(pageId, block, null);
});
},
addPageToExperience: function(pageName, pageTemplate, path, aceAppSysId) {
var pageId = this._grRecordCreator(this.TABLE.PAGE, {
'name': pageName,
'ace_app': aceAppSysId,
'template': pageTemplate,
'path': path
});
return pageId;
},
createExperience: function(name, urlPath, landingPath, aceAppSysId, createDemoData, current) {
var _self = this;
if (createDemoData) this.CREATE_DEMO_DATA = true;
var appConfig = this.GLOBAL._grRecordCreator(_self.UXF_TABLE.APP_CONFIG, {
'name': name,
'landing_path': landingPath
});
var experience = this.GLOBAL._grRecordCreator(_self.UXF_TABLE.PAGE_REGISTRY, {
'title': name,
'admin_panel_table': _self.UXF_TABLE.APP_CONFIG,
'admin_panel': appConfig,
'path': urlPath,
'parent_app': _self.CONSTANTS.BASE_UXF_RECORDS.PARENT_APP,
'root_macroponent': _self.CONSTANTS.BASE_UXF_RECORDS.APP_SHELL_UI
});
var pagePropertyPayload = {
'page': experience,
'name': 'ace_application_id',
'type': 'string',
'value': aceAppSysId,
'description': 'ACE Record id for this Experience'
};
var chromeHeaderPagePropertyPayload = {
'page': experience,
'name': 'chrome_header',
'type': 'json',
'value': JSON.stringify(_self.CONSTANTS.CHROME_HEADER_VALUE),
};
this.GLOBAL._grRecordCreator(_self.UXF_TABLE.PAGE_PROPERTY, pagePropertyPayload);
this.GLOBAL._grRecordCreator(_self.UXF_TABLE.PAGE_PROPERTY, chromeHeaderPagePropertyPayload);
// Update the current variable directly here with required info
var context = this._createFactories(appConfig, aceAppSysId, name);
if (current) {
current.app_config = appConfig;
current.context = JSON.stringify(context);
current.update();
}
var shippedPages = _self.CONSTANTS.DEFAULT_PAGES;
shippedPages.forEach(function(pageInfo) {
_self.addPageToExperience(pageInfo.name, pageInfo.template, pageInfo.path, aceAppSysId);
});
return appConfig;
},
constructNavMenuItems: function(menuItems, parentId) {
var _self = this;
menuItems.forEach(function(menuItem) {
menuItem.label = menuItem.title;
menuItem.id = menuItem.block_id;
_self.constructNavMenuItems(menuItem.children);
});
},
/*_getPageIdFromRoute: function(aceAppSysId, pageRoute) {
if (!aceAppSysId || !pageRoute) return null;
var gr = new GlideRecord(this.TABLE.PAGE);
gr.addQuery('name', pageRoute);
gr.addQuery('ace_app', aceAppSysId);
gr.query();
if (gr.next()) {
return gr.getValue('sys_id');
}
return null;
},*/
_buildLink: function(gr) {
var link = '';
switch (gr.getValue('link_type')) {
case 'guided_setup':
link = '/$guided_setup.do#/content/' + gr.getValue('guided_setup_id');
var focus_id = gr.getValue('foucus_id');
if (focus_id != '') {
link += '?focus=' + focus_id;
}
break;
case 'record':
link = '/' + gr.getValue('list_table') + '.do?sys_id=' + gr.getValue('record');
break;
case 'list':
link = '/' + gr.getValue('list_table') + '_list.do?sysparm_query=' + gr.getValue('list_query');
break;
case 'custom':
default:
link = gr.getValue('link_url');
}
return link;
},
_getPluginsInfo: function(plugins) {
if (!plugins) return [];
var pluginList = plugins.split(',');
return pluginList.map(function(plugin) {
var grPlugin = new GlideRecord('v_plugin');
grPlugin.get(plugin);
return {
"id": plugin,
"label": grPlugin.getValue('name'),
"selected": true,
"type": "plugin",
"use_demo_data": false
};
});
},
_areAllPluginsActive: function(plugins) {
if (!plugins) return false;
var pluginList = plugins.split(',');
return !pluginList.some(function(plugin) {
var grPlugin = new GlideRecord('v_plugin');
grPlugin.get(plugin);
return grPlugin.getValue('active') !== 'active';
});
},
_mapCards: function(registry) {
var mappedCards = [];
try {
registry.card_order.forEach(function(parentCardId) {
var screens = [];
screens.push(registry.definitions[parentCardId]);
registry.maps[parentCardId].forEach(function(childCardId) {
screens.push(registry.definitions[childCardId]);
});
mappedCards.push(screens);
});
return mappedCards;
} catch (e) {
return mappedCards;
}
},
_parseSysProperties: function(propsSysIdList) {
var props = [];
try {
var gr = new GlideRecord('sys_properties');
gr.addQuery('sys_id', 'IN', propsSysIdList);
gr.query();
while (gr.next()) {
props.push({
'name': gr.getValue('name'),
'value': gr.getValue('value') == 'true',
'description': gr.getValue('description')
});
}
return props;
} catch (e) {
return props;
}
},
syncSysProperties: function(propsList) {
var _self = this;
if (!propsList) return false;
if (!Array.isArray(propsList)) return false;
if (propsList.length == 0) return false;
try {
propsList.forEach(function(property) {
if (_self.GLOBAL._getSysProperty(property.name) != property.value.toString())
_self.GLOBAL._updateSysProperty(property.name, property.value);
});
return true;
} catch (e) {
return false;
}
},
_getChartConfig: function(gr) {
try {
var config = JSON.parse(gr.getValue('chart_config'));
config.chart_type = gr.getValue('chart_type');
return config;
} catch (e) {
return {
"chart_type": "donut",
"title": "Basic Chart",
"table": "problem",
"query": "active=true"
};
}
},
_isParentChildTypeEqual: function(gr) {
if (!gr.parent) return false;
return gr.parent.category.toString() == gr.category.toString() &&
gr.parent.type.toString() == gr.type.toString();
},
_getGlideVarsForType: function(type) {
var variables = [];
var gr = new GlideRecord(this.TABLE.VARIABLE);
gr.addQuery('model', type);
gr.query();
while (gr.next()) {
variables.push({
'element': gr.getValue('element'),
'type': gr.getValue('internal_type')
});
}
return variables;
},
_setGlideVars: function(table, recordId, glideVariableObject) {
try {
var gr = new GlideRecord(table);
if (gr.get(recordId)) {
for (var gVariable in glideVariableObject) {
gr.variable[gVariable] = glideVariableObject[gVariable];
}
return gr.update();
}
return false;
} catch (e) {
return false;
}
},
_getContentBlocksRowCountOnly: function(customQuery) {
try {
return this._getContentBlocks('', customQuery).length;
} catch (e) {
return 0;
}
},
getAllContentBlockTypes: function(table) {
var types = {},
_self = this;
var gr = new GlideRecord(table);
gr.query();
while (gr.next()) {
var typeId = gr.getUniqueValue();
types[typeId] = {
'group': gr.category.toString(),
'name': gr.name.toString(),
'id': typeId,
'route': gr.route.toString(),
'props': _self._getGlideVarsForType(typeId)
};
}
return types;
},
_getDetailedType: function(typeSysId) {
return this.ALL_CONTENT_BLOCK_TYPES[typeSysId];
},
_variableScriptEvaluator: function(gr, cbScriptVariables, cbData) {
var _self = this;
try {
var evaluator = new GlideScopedEvaluator();
evaluator.putVariable('pageId', cbScriptVariables.pageId);
evaluator.putVariable('pageParams', cbScriptVariables.pageParams);
var aceVarGr = new GlideRecord(this.TABLE.VARIABLE);
aceVarGr.addQuery('model', cbData.type.id);
aceVarGr.query();
if (aceVarGr.next()) {
var sysVarGr = new GlideRecord('sys_variable_value');
sysVarGr.addQuery('document_key', cbData.block_id);
sysVarGr.addQuery('variable', aceVarGr.getValue('sys_id'));
sysVarGr.query();
try {
if (sysVarGr.next())
return evaluator.evaluateScript(sysVarGr, 'value', null);
} catch (e) {
gs.error('Error while evaluating Script: ' + e.toString());
}
}
} catch (e) {
gs.error('Error while evaluating Script: ' + e.toString());
}
return [];
},
_evaluateCBScriptVariables: function(gr, cbData, cbScriptVariables) {
var _self = this;
var typeObject = cbData.type;
if (typeObject && typeObject.props && Array.isArray(typeObject.props) > 0) {
typeObject.props.forEach(function(propItem) {
if (propItem.type === "script")
cbData.props_details[propItem.element] = _self._variableScriptEvaluator(gr, cbScriptVariables, cbData);
});
}
},
_sanitize: function(value, parseBoolean) {
if (value == null || value == undefined) return '';
if (parseBoolean) {
if (value.toString() == 'true') return '1';
if (value.toString() == 'false') return '0';
}
return value.toString();
},
/* dataSource = GlideRecord instance [OR] Cached Data*/
_getContentBlockInfo: function(dataSource, cbId, pageParams) {
var _self = this;
try {
var typeObject = _self._getDetailedType(_self._sanitize(dataSource.type));
//id and label property is required for content tree component
var contentBlockInfo = {
'block_id': cbId,
'id': cbId,
'parent_block_id': dataSource.parent.toString(),
'active': dataSource.active.toString() === 'true' ? true : false,
'name': _self._sanitize(dataSource.name),
'label': _self._sanitize(dataSource.name),
'title': _self._sanitize(dataSource.title),
'subtitle': _self._sanitize(dataSource.subtitle),
'order': _self._sanitize(dataSource.order),
'type': typeObject,
'lazyLoad': _self._sanitize(dataSource.lazy_load, true),
'children': [],
'props_details': {},
'props_details_display': {},
'pageParams': pageParams
};
if (typeObject && typeObject.props && Array.isArray(typeObject.props) > 0) {
typeObject.props.forEach(function(propItem) {
contentBlockInfo.props_details[propItem.element] = dataSource.variable[propItem.element].toString();
if (propItem.type == 'reference') {
var dictionary = new GlideRecord('sys_dictionary');
dictionary.addQuery('sys_id', _self._sanitize(dataSource.variable[propItem.element]));
dictionary.query();
if (dictionary.next()) {
contentBlockInfo.props_details_display[propItem.element] = dictionary.getValue('element');
}
}
});
}
return contentBlockInfo;
} catch (e) {
gs.error('ACEAppBuilderUtil: Error while fetching content block info: ' + e.toString());
return contentBlockInfo;
}
},
_getExperienceIdFromCBId: function(cbId) {
if (!cbId) return null;
var gr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
if (gr.get(cbId)) {
return gr.getValue('ace_config');
}
return null;
},
_getExperienceIdFromCBQuery: function(cbQuery) {
if (!cbQuery || !cbQuery.document_table || !cbQuery.document_id) return null;
var _self = this;
switch (cbQuery.document_table) {
case _self.TABLE.PAGE:
var gr = new GlideRecord(_self.TABLE.PAGE);
if (gr.get(cbQuery.document_id)) {
return gr.getValue('ace_app');
}
return null;
case _self.TABLE.APP_CONFIG:
return cbQuery.document_id;
default:
return null;
}
},
_buildCachedContentBlocks: function(experienceId, cbQuery, parentId, cbScriptVariables) {
var cachedContentBlocks = [],
_self = this;
//check for user roles access sn_ace.ace_user
if (!this.CAN_READ) return cachedContentBlocks;
//attach the parent query to the existing query. NOTE: For cached content, parent == '' IS_NOT_EQUAL parent == null
if (!cbQuery) cbQuery = {};
cbQuery['parent'] = parentId;
cbQuery['active'] = '1';
var cachedCBs = this.GLOBAL.getContentBlocksFromCache(experienceId, cbQuery);
if (!cachedCBs) return null;
//Try creating a Virtual GlideRecord instance using the parentId required for GlideScopeEvaluator. Re-use this for evaluation to reduce queries.
var virtualGr = _self.VIRTUAL_GR || _self._getVirtualGrInstance(parentId);
if (!_self.VIRTUAL_GR && virtualGr) _self.VIRTUAL_GR = virtualGr;
cachedCBs.forEach(function(cachedCB) {
var cbId = cachedCB.sys_id;
//Re-try the Virtual GR creation again with cbId (since parentId is null) and register it in app level
virtualGr = _self.VIRTUAL_GR || _self._getVirtualGrInstance(cbId);
if (!_self.VIRTUAL_GR && virtualGr) _self.VIRTUAL_GR = virtualGr;
if (_self._cachedScriptEvaluator(virtualGr, 'visibility', cachedCB.visibility, null)) {
var cachedCBData = _self._getContentBlockInfo(cachedCB, cbId);
_self._evaluateCBScriptVariables(virtualGr, cachedCBData, cbScriptVariables);
cachedCBData.children = _self._buildCachedContentBlocks(experienceId, cbQuery, cbId, cbScriptVariables);
_self._cachedScriptEvaluator(virtualGr, 'post_script', cachedCB.post_script, cachedCBData);
cachedContentBlocks.push(cachedCBData);
}
});
return cachedContentBlocks;
},
_getContentBlocksFromCache: function(parentId, cbQuery, cbScriptVariables) {
try {
//get and register the experience id in app level to reduce queries
var experienceId = this.EXPERIENCE_ID || this._getExperienceIdFromCBId(parentId) || this._getExperienceIdFromCBQuery(cbQuery);
if (!experienceId) return null;
if (!this.EXPERIENCE_ID) this.EXPERIENCE_ID = experienceId;
//try to fetch content blocks from cache
var cachedContentBlocks = this._buildCachedContentBlocks(experienceId, cbQuery, parentId, cbScriptVariables);
//if not present, try to build the cache for this experience
if (!cachedContentBlocks || (Array.isArray(cachedContentBlocks) && cachedContentBlocks.length == 0)) {
this.GLOBAL.buildExperienceCache(experienceId);
//retry fetching the content blocks from the recenly built cache
cachedContentBlocks = this._buildCachedContentBlocks(experienceId, cbQuery, parentId, cbScriptVariables);
}
return cachedContentBlocks;
} catch (e) {
return null;
}
},
_getContentBlocks: function(parentId, customQuery, cbScriptVariables) {
var contentBlocks = [];
cbScriptVariables = cbScriptVariables || {};
//fetch and return from cache if present
// if (this.GLOBAL._isCacheEnabled()) {
// var cachedContentBlocks = this._getContentBlocksFromCache(parentId, customQuery, cbScriptVariables);
// if (cachedContentBlocks) return cachedContentBlocks;
// }
//if no cached content blocks present, use GlideRecord to query from table
var _self = this;
try {
this.gr_counter += 1;
var gr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
gr.addQuery('parent', parentId);
gr.addQuery('active', true);
for (var q in customQuery) {
gr.addQuery(q, customQuery[q]);
}
gr.orderBy('order');
gr.query();
while (gr.next()) {
if (!_self._visibilityEvaluator(gr, cbScriptVariables.pageParams)) continue;
var cbId = gr.getUniqueValue();
var cbData = _self._getContentBlockInfo(gr, cbId, cbScriptVariables.pageParams);
// content block variable script evaluator
_self._evaluateCBScriptVariables(gr, cbData, cbScriptVariables);
cbData.children = _self._getContentBlocks(cbId, customQuery, cbScriptVariables);
//post script evaluator
_self._evaluatePostScript(gr, cbData, cbScriptVariables.pageParams);
contentBlocks.push(cbData);
}
} catch (e) {
gs.error('ACEAppBuilderUtil: Error while fetching content blocks: ' + e.toString());
}
return contentBlocks;
},
_getFetchMode: function(cbQuery) {
//Experience level System Property value (ace.content_blocks.fetch.mode.<EXPERIENCE ID>)
var experienceId = this._getExperienceIdFromCBQuery(cbQuery);
if (!experienceId) return this.DEFAULT_FETCH_MODE;
var mode = gs.getProperty('ace.content_blocks.fetch.mode.' + experienceId, 'dfs');
mode = mode.toLowerCase();
if (this.SUPPORTED_FETCH_MODES.indexOf(mode) != -1) return mode;
return this.DEFAULT_FETCH_MODE;
},
getContentBlocks: function(pageId, pageParams) {
var _self = this;
if (!this.CAN_READ) return [];
var cbQuery = {
'document_table': _self.TABLE.PAGE,
'document_id': pageId
};
var cbPageParams = {
'pageId': pageId,
'pageParams': pageParams
};
var fetchMode = this._getFetchMode(cbQuery);
gs.info('Admin Experience Framework Content Blocks fetching mode: ' + fetchMode);
if (fetchMode === this.DEFAULT_FETCH_MODE) {
return this._getContentBlocks(null, cbQuery, cbPageParams);
}
return this._getContentBlocksBFS(null, cbQuery, cbPageParams);
},
getAllContentBlocksBFS: function() {
return this._getContentBlocksBFS(null, {}, {});
},
_appendContentBlockschildren: function(contentBlocksMap, cbId, cbContextObj) {
if (!contentBlocksMap[cbId]) return [];
var result = [];
contentBlocksMap[cbId].forEach(function(cbChildId) {
if (cbContextObj[cbChildId]) {
result.push(JSON.parse(JSON.stringify(cbContextObj[cbChildId])));
//delete cbContextObj[cbChildId];
}
});
return result;
},
_processContentBlocksFromIds: function(contentBlocksMap, contentBlockParentIds, cbContextObj, cbScriptVariables, cbLevel, nextCBLevel) {
var _self = this;
this.gr_counter += 1;
var gr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
if (!contentBlockParentIds) gr.addQuery('parent', '');
else gr.addQuery('parent', 'IN', contentBlockParentIds.toString());
gr.orderBy('order');
gr.query();
while (gr.next()) {
var cbId = gr.getUniqueValue().toString();
if (cbLevel[nextCBLevel] && cbLevel[nextCBLevel].indexOf(cbId) == -1) continue;
var cbData = _self._getContentBlockInfo(gr, cbId, cbScriptVariables.pageParams);
// content block variable script evaluator
_self._evaluateCBScriptVariables(gr, cbData, cbScriptVariables);
//append children
cbData.children = _self._appendContentBlockschildren(contentBlocksMap, cbId, cbContextObj);
//post script evaluator
_self._evaluatePostScript(gr, cbData, cbScriptVariables.pageParams);
cbContextObj[cbId] = cbData;
}
},
_buildContentBlockTreeFromLevels: function(contentBlocksMap, cbLevel, cbScriptVariables) {
//loop through last-but-one level to 0
var _self = this;
var cbContextObj = {};
var contentBlocks = [];
for (var level = (cbLevel.length - 2); level >= 0; level--) {
var contentBlockParentIds = cbLevel[level];
_self._processContentBlocksFromIds(contentBlocksMap, contentBlockParentIds, cbContextObj, cbScriptVariables, cbLevel, (level + 1));
}
_self._processContentBlocksFromIds(contentBlocksMap, '', cbContextObj, cbScriptVariables, cbLevel, 0);
//if only root level content blocks are present
if (!contentBlockParentIds) contentBlockParentIds = cbLevel[0];
contentBlockParentIds.forEach(function(contentBlockParentId) {
contentBlocks.push(cbContextObj[contentBlockParentId]);
});
return contentBlocks;
},
_buildContentBlockLevels: function(cbMap, cbIds, cbLevelObject, level) {
if (!cbLevelObject[level]) cbLevelObject[level] = [];
var _self = this;
cbIds.forEach(function(blockId) {
cbLevelObject[level].push(blockId);
if (cbMap[blockId] && cbMap[blockId].length > 0) {
_self._buildContentBlockLevels(cbMap, cbMap[blockId], cbLevelObject, (level + 1));
}
});
},
_getValidCBIds: function(base, blacklist) {
var validIds = [];
base.forEach(function(cbId) {
if (blacklist.indexOf(cbId) == -1) validIds.push(cbId);
});
return validIds;
},
_visibilityCheck: function(cbLevels, cbLevelIndex, blacklistedCBIds, cbScriptVariables) {
if (cbLevelIndex == cbLevels.length && cbLevelIndex >= 0) {
return cbLevels;
}
this.gr_counter += 1;
var gr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
gr.addQuery('active', true);
if (cbLevelIndex < 0) {
gr.addQuery('sys_id', 'IN', cbLevels[0]);
} else {
var validIds = this._getValidCBIds(cbLevels[cbLevelIndex], blacklistedCBIds);
if (validIds.length === 0) return cbLevels;
gr.addQuery('parent', 'IN', validIds.toString());
}
gr.orderBy('order');
gr.query();
var cbs = [];
while (gr.next()) {
var cbId = gr.getUniqueValue().toString();
if (!this._visibilityEvaluator(gr, cbScriptVariables.pageParams)) {
blacklistedCBIds.push(cbId);
} else {
cbs.push(cbId);
}
}
if (cbs.length)
cbLevels[cbLevelIndex + 1] = cbs;
return this._visibilityCheck(cbLevels, (cbLevelIndex + 1), blacklistedCBIds, cbScriptVariables);
},
/**
* BFS Approach:
* Step 1: Get ALL the content blocks of a page orderby 'order'
* Step 2: Build the parent-child sys_id relationship map. Example:
* {
* '_root': ['cb_id#1', 'cb_id#2', 'cb_id#3'],
* 'cb_id#1': ['cb_id#1.child#1', 'cb_id#1.child#2', 'cb_id#1.child#3'],
* 'cb_id#2': ['cb_id#2.child#1', 'cb_id#2.child#2'],
* 'cb_id#3': ['cb_id#3.child#1', 'cb_id#3.child#2', 'cb_id#3.child#3', 'cb_id#3.child#4'],
* 'cb_id#1.child#1': ['cb_id#1.child#1.child#1', ...],
* ...
* }
* Step 3: Build the step-level hierarchy of the map. Example:
* [
* ['cb_id#1', 'cb_id#2', 'cb_id#3'],
* ['cb_id#1.child#1', 'cb_id#1.child#2', 'cb_id#1.child#3', 'cb_id#2.child#1', 'cb_id#2.child#2', 'cb_id#3.child#1', 'cb_id#3.child#2', 'cb_id#3.child#3', 'cb_id#3.child#4'],
* ['cb_id#1.child#1.child#1', ...],
* ...
* ]
* Step 4: Using a top-down approach evaluate the visibility script and modify the step-level hierarchy.
* Example: For, 'cb_id#2' = false
* [
* ['cb_id#1', 'cb_id#3'],
* ['cb_id#1.child#1', 'cb_id#1.child#2', 'cb_id#1.child#3', 'cb_id#3.child#1', 'cb_id#3.child#2', 'cb_id#3.child#3', 'cb_id#3.child#4'],
* ['cb_id#1.child#1.child#1', ...],
* ...
* ]
* Step 5: Using a bottom-up approach evaluate the post script and build the Content Block contract
*/
_getContentBlocksBFS: function(parentId, customQuery, cbScriptVariables) {
try {
var contentBlocksMap = {
'_root': []
};
this.gr_counter += 1;
//Step 1,2: get all content blocks and build the parent-child relationship map of their sys_ids
var gr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
for (var q in customQuery) {
gr.addQuery(q, customQuery[q]);
}
if (parentId) {
gr.addQuery('parent', parentId);
}
gr.orderBy('order');
gr.query();
while (gr.next()) {
var blockId = gr.getUniqueValue();
var parentBlockId = gr.getValue('parent');
if (!parentBlockId) contentBlocksMap._root.push(blockId);
else {
if (!contentBlocksMap[parentBlockId]) contentBlocksMap[parentBlockId] = [];
contentBlocksMap[parentBlockId].push(blockId);
}
}
var contentBlocksLevel = [];
//Step 3: build a 2D array of the step-level hierarchy
this._buildContentBlockLevels(contentBlocksMap, contentBlocksMap._root, contentBlocksLevel, 0);
//Step 4: modify the same 2D array of the step-level hierarchy after removing visible false items
contentBlocksLevel = this._visibilityCheck(contentBlocksLevel, -1, [], cbScriptVariables);
//Step 5: build the content block contract
var contentBlocks = this._buildContentBlockTreeFromLevels(contentBlocksMap, contentBlocksLevel, cbScriptVariables);
return contentBlocks;
} catch (e) {
gs.error('ACEAppBuilderUtil: Error while fetching content blocks: ' + e.toString());
return [];
}
},
getContentBlockPayload: function(cbId, pageParams, includeChildBlocks) {
var cbData = {};
var cbScriptVariables = {
'pageParams': pageParams
};
if (!this.CAN_READ) return cbData;
var gr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
if (cbId && gr.get(cbId)) {
// TODO: Should we check for visibility in lazy load again?
cbData = this._getContentBlockInfo(gr, cbId, pageParams);
this._evaluateCBScriptVariables(gr, cbData, cbScriptVariables);
if (includeChildBlocks) {
// content block variable script evaluator
cbData.children = this._getContentBlocks(cbId, {}, cbScriptVariables);
//post script evaluator
_self._evaluatePostScript(gr, cbData, pageParams);
}
this._evaluateLazyScript(gr, cbData, pageParams);
}
return cbData;
},
_getUrlPath: function(urlPath, route) {
return '/now' + '/' + urlPath + '/' + route.toLowerCase();
},
getMenuItems: function(aceAppId, moduleSysId, routeParams) {
var _self = this;
var menuItems = [];
try {
menuItems = _self._getContentBlocks(moduleSysId, {
'document_table': _self.TABLE.APP_CONFIG,
'document_id': aceAppId,
'type': _self.CONSTANTS.CONTENT_BLOCK_TYPES.NAV
}, {
pageParams: routeParams
});
_self.constructNavMenuItems(menuItems);
return menuItems;
} catch (e) {
return menuItems;
}
},
getFieldsAndParams: function(routeId) {
var routeGr = new GlideRecord('sys_ux_app_route');
var result = {
fields: [],
params: []
};
if (routeGr.get(routeId)) {
var fields = routeGr.getValue('fields') || '';
result.fields = fields.split(',').filter(function(field) {
return field;
}).map(function(field) {
return {
name: field
};
});
var params = routeGr.getValue('optional_parameters') || '';
result.params = params.split(',').filter(function(param) {
return param;
}).map(function(param) {
return {
name: param
};
});
}
return result;
},
getModulePath: function(urlPath, modulePath, routeId, page_parameters) {
var _self = this;
var path = _self._getUrlPath(urlPath, modulePath);
var uxfPageParams = _self.getFieldsAndParams(routeId);
if (page_parameters) {
page_parameters = JSON.parse(page_parameters);
uxfPageParams.fields.concat(uxfPageParams.params).forEach(function(param) {
var name = param.name;
if (page_parameters[name])
path = path + '/' + page_parameters[name].toString();
});
}
return path;
},
getModules: function(aceAppId, urlPath, routeParams) {
var _self = this;
if (!this.CAN_READ) return [];
var modules = this._getContentBlocks(null, {
'document_table': this.TABLE.APP_CONFIG,
'document_id': aceAppId,
'type': this.CONSTANTS.CONTENT_BLOCK_TYPES.MODULE
});
//massage modules blocks to support UI
//TODO: Make UI in sync with content_blocks contract
modules.forEach(function(module) {
module.isActive = false;
var containedPages = module.props_details.contained_pages;
module.props_details.contained_pages = containedPages ? _self.getContainedPagesRoutes(containedPages) : containedPages;
module.menu = _self.getMenuItems(aceAppId, module.block_id, routeParams);
// Module Page Route Should be atken from prop details
var pageId = module.props_details.ace_page;
var gr = new GlideRecord(_self.TABLE.PAGE);
if (pageId && gr.get(pageId)) {
module.page_route = gr.getValue('path');
module.path = _self.getModulePath(urlPath, module.page_route, gr.route.toString(), module.props_details.page_parameters);
} else if (module.props_details.link) module.path = module.props_details.link;
else gs.addErrorMessage(gs.getMessage("Please provide input for either acepage or link fields"));
});
return modules;
},
getContainedPagesRoutes: function(containedPages) {
var _self = this;
var contained_pages_routes = [];
var ace_page_gr = new GlideRecord(_self.TABLE.PAGE);
ace_page_gr.addQuery('sys_id', 'IN', containedPages);
ace_page_gr.query();
while (ace_page_gr.next()) {
contained_pages_routes.push(ace_page_gr.getValue('path'));
}
return contained_pages_routes;
},
getURLPath: function(uxAppConfigId) {
var url_path = '';
var sys_ux_page_registry_gr = new GlideRecord(this.CONSTANTS.UXF_TABLES.PAGE_REGISTRY);
sys_ux_page_registry_gr.addQuery('admin_panel', uxAppConfigId);
sys_ux_page_registry_gr.query();
if (sys_ux_page_registry_gr.next()) {
url_path = sys_ux_page_registry_gr.getValue('path');
}
return url_path;
},
getAceAppData: function(aceAppConfig, routeParams) {
var _self = this;
var onLoadData = {
'modules': []
};
try {
var gr = new GlideRecord(this.TABLE.APP_CONFIG);
if (gr.get(aceAppConfig)) {
onLoadData.modules = _self.getModules(aceAppConfig, _self.getURLPath(gr.getValue('app_config')), routeParams);
onLoadData.isSearchConfigured = _self.fetchSearchConfig(aceAppConfig) ? true : false;
}
return onLoadData;
} catch (e) {
return onLoadData;
}
},
_createDemoBlocksInPage: function(pageId) {
var _self = this;
this._createContentBlocks(pageId, this.demoUtils.getDemoTemplate());
},
_createDemoData: function(pageName, pageId, moduleId) {
// TODO: Add this demo data while creating the app
if (!this.CREATE_DEMO_DATA) return;
},
_createFactories: function(appConfigId, aceAppSysId, appName) {
var contentOutput = this.createPage(appConfigId, appName + ' - ACE Content Factory', aceAppSysId, 'Content Factory');
var containerOutput = this.createPage(appConfigId, appName + ' - ACE Container Factory', aceAppSysId, 'Container Factory');
return this._patchFactories(contentOutput.macroponent, containerOutput.macroponent);
},
_deleteUXFPage: function(routeId) {
// TODO: Replace this method with UXF apis in app builder
var routeGr = new GlideRecord(this.UXF_TABLE.APP_ROUTE);
if (!routeGr.get(routeId)) return;
var screenTypeGr = new GlideRecord(this.UXF_TABLE.SCREEN_TYPE);
if (!screenTypeGr.get(routeGr.getValue('screen_type'))) return;
var screenGr = new GlideRecord(this.UXF_TABLE.SCREEN);
screenGr.addQuery('screen_type', routeGr.getValue('screen_type'));
screenGr.query();
while (screenGr.next()) {
this.GLOBAL.deleteRecord(this.UXF_TABLE.SCREEN, screenGr.getUniqueValue());
}
var macroponentGr = new GlideRecord(this.UXF_TABLE.MACROPONENT);
if (!macroponentGr.get(screenGr.getValue('macroponent'))) return;
this.GLOBAL.deleteRecord(this.UXF_TABLE.APP_ROUTE, routeGr.getUniqueValue());
this.GLOBAL.deleteRecord(this.UXF_TABLE.SCREEN_TYPE, screenTypeGr.getUniqueValue());
this.GLOBAL.deleteRecord(this.UXF_TABLE.MACROPONENT, macroponentGr.getUniqueValue());
},
_createContentBlock: function(configId, inputDocId, templateId, documentTable, searchPageId) {
var _self = this;
var cbGr = new GlideRecord(_self.TABLE.CONTENT_BLOCK);
cbGr.addQuery('document_id', templateId);
cbGr.addQuery('document_table', documentTable);
cbGr.query();
while (cbGr.next()) {
var props_details = {};
var props = _self._getGlideVarsForType(cbGr.type.toString());
if (props && Array.isArray(props) > 0) {
props.forEach(function(propItem) {
props_details[propItem.element] = cbGr.variable[propItem.element].toString();
});
}
var cbId = _self._grRecordCreator(_self.TABLE.CONTENT_BLOCK, {
name: cbGr.getValue('name'),
title: cbGr.getValue('title'),
subtitle: cbGr.getValue('subtitle'),
order: cbGr.getValue('order'),
type: cbGr.type,
parent: cbGr.parent,
post_script: cbGr.getValue('post_script'),
visibility: cbGr.getValue('visibility'),
active: cbGr.getValue('active'),
ace_config: configId,
document_id: inputDocId,
document_table: documentTable
});
if (searchPageId && cbGr.getValue('name') === _self.CONSTANTS.SEARCH_CONTENT_BLOCK) {
props_details['page'] = searchPageId;
}
_self._setGlideVars(_self.TABLE.CONTENT_BLOCK, cbId, props_details);
}
},
createContentBlock: function(configId, pageId) {
var _self = this;
if (!this.CAN_READ) return;
var baseGr = new GlideRecord(_self.TABLE.PAGE);
if (pageId && baseGr.get(pageId)) {
var templatePageId = baseGr.getValue('template');
_self._createContentBlock(configId, pageId, templatePageId, _self.TABLE.PAGE);
}
},
_patchPage: function(aceAppId, pageId, macroponentId, screenType) {
var context = {};
if (!this.CAN_READ) return null;
var gr = new GlideRecord(this.TABLE.APP_CONFIG);
if (gr.get(aceAppId)) {
context = JSON.parse(gr.getValue('context'));
}
if (!this._updateMacroponentProp(macroponentId, 'data', this.CONSTANTS.BASE_UXF_RECORDS.SECTIONS_DATA_BROKER_NAME, 'page_route', pageId)) {
//code logic
}
// FIXME: there are multiple updates to macroponent here.. Consolidate it into one
try {
// Update content block factory sysIds in each page composition
var macroGr = new GlideRecord(this.UXF_TABLE.MACROPONENT);
if (macroGr.get(macroponentId)) {
var composition = macroGr.getValue('composition');
var newComposition = this._replaceAll(composition, this.CONSTANTS.BASE_UXF_RECORDS.CONTENT_BLOCK.MACROPONENT, context.content_block_id);
this.GLOBAL.updateRecord(this.UXF_TABLE.MACROPONENT, macroponentId, {
composition: newComposition
});
}
// Update route field on ace_page record if screenType is supplied
if (screenType) {
var routeGr = new GlideRecord(this.UXF_TABLE.APP_ROUTE);
routeGr.addQuery('screen_type', screenType);
routeGr.query();
if (routeGr.next()) {
var pageGr = new GlideRecord(this.TABLE.PAGE);
if (pageGr.get(pageId) && pageGr.canWrite()) {
pageGr.setValue('route', routeGr.getUniqueValue());
pageGr.update();
}
}
}
// FIXME: These record updates maynot work from a different scope. Try to use Global update script include
} catch (e) {
return null;
}
},
updateAppConfigForSubPagesRoutes: function(screenType, contentBlockId) {
var _self = this;
var screen = new GlideRecord(this.UXF_TABLE.SCREEN);
screen.get('screen_type', screenType);
var appConfig = screen.app_config;
var route_gr = new GlideRecord(this.UXF_TABLE.APP_ROUTE);
route_gr.addQuery('parent_macroponent', contentBlockId);
route_gr.addQuery('app_config', this.CONSTANTS.BASE_UXF_RECORDS.ACE_BASE_EXPERIENCE_APP_CONFIG);
route_gr.query();
while (route_gr.next()) {
var route_id = route_gr.sys_id;
this.GLOBAL.updateRecord(_self.UXF_TABLE.APP_ROUTE, route_id, {
'app_config': appConfig
});
}
},
getContentBlockSubPages: function(appName) {
var self = this;
var sub_pages_list = [];
var clone_macroponent_routes = self.CONSTANTS.CLONE_ROUTES;
var content_block_routes_gr = new GlideRecord(self.UXF_TABLE.APP_ROUTE);
content_block_routes_gr.addQuery('app_config', self.CONSTANTS.BASE_UXF_RECORDS.ACE_BASE_EXPERIENCE_APP_CONFIG);
content_block_routes_gr.addQuery('parent_macroponent', self.CONSTANTS.BASE_UXF_RECORDS.CONTENT_BLOCK.MACROPONENT);
content_block_routes_gr.query();
while (content_block_routes_gr.next()) {
var cloneMacroponent = clone_macroponent_routes.some(function(route) {
return route === content_block_routes_gr.getValue('route_type');
});
var screen_gr = new GlideRecord(self.UXF_TABLE.SCREEN);
screen_gr.get('screen_type', content_block_routes_gr.getValue('screen_type'));
sub_pages_list.push({
MACROPONENT: screen_gr.getValue('macroponent'),
SCREEN: screen_gr.getValue('sys_id'),
SCREEN_TYPE: content_block_routes_gr.getValue('screen_type'),
NAME: appName + " - " + content_block_routes_gr.getValue('name'),
ROUTE: content_block_routes_gr.getValue('route_type'),
CLONE_MACROPONENT: cloneMacroponent
});
}
return sub_pages_list;
},
_cloneMacroponentForSubpage: function(baseMacroponentId, subPageName, appContentBlockId) {
var self = this;
var content_block = self._getConstantsForPage('Content Block');
var macroponentCloneInfo = {
'sys_id': baseMacroponentId,
'fields': self.CONSTANTS.CLONE_FIELDS.MACROPONENT
};
// create new subpage macroponent
var newMacroponentId = self.GLOBAL._grRecordCreator(self.UXF_TABLE.MACROPONENT, {
'name': subPageName
}, macroponentCloneInfo);
var macroponentGr = new GlideRecord(self.UXF_TABLE.MACROPONENT);
if (!macroponentGr.get(newMacroponentId)) {
return;
}
// patch it with base composition
self.GLOBAL.updateRecord(self.UXF_TABLE.MACROPONENT, newMacroponentId, {
'composition': self._replaceAll(macroponentGr.getValue('composition'), content_block.MACROPONENT, appContentBlockId)
});
// ensure success
macroponentGr = new GlideRecord(self.UXF_TABLE.MACROPONENT);
if (!macroponentGr.get(newMacroponentId)) {
return;
}
return macroponentGr;
},
_updateNewMacroponentWithScripts: function(newMacroponentGr, clientScriptMaps, newMacroponentId) {
var self = this;
var postUpdate = {
'composition': newMacroponentGr.getValue('composition'),
'data': newMacroponentGr.getValue('data'),
'state_properties': newMacroponentGr.getValue('state_properties'),
'internal_event_mappings': newMacroponentGr.getValue('internal_event_mappings'),
};
clientScriptMaps.forEach(function(clientScriptMap) {
postUpdate.composition = self._replaceAll(
postUpdate.composition,
clientScriptMap.findId,
clientScriptMap.replaceWithId
);
postUpdate.data = self._replaceAll(
postUpdate.data,
clientScriptMap.findId,
clientScriptMap.replaceWithId
);
postUpdate.state_properties = self._replaceAll(
postUpdate.state_properties,
clientScriptMap.findId,
clientScriptMap.replaceWithId
);
postUpdate.internal_event_mappings = self._replaceAll(
postUpdate.internal_event_mappings,
clientScriptMap.findId,
clientScriptMap.replaceWithId
);
});
self.GLOBAL.updateRecord(self.UXF_TABLE.MACROPONENT, newMacroponentId, postUpdate);
},
_createScreenTypeForSubPage: function(subPage) {
var self = this;
var screenTypeCloneInfo = {
'sys_id': subPage.SCREEN_TYPE,
'fields': self.CONSTANTS.CLONE_FIELDS.SCREEN_TYPE
};
var newScreenTypeId = self.GLOBAL._grRecordCreator(self.UXF_TABLE.SCREEN_TYPE, {
'name': subPage.NAME
},
screenTypeCloneInfo);
return newScreenTypeId;
},
_createScreenForSubPage: function(subPage, newMacroponentId, appConfig, newScreenTypeId, appContentBlockId) {
var self = this;
var screenCloneInfo = {
'sys_id': subPage.SCREEN,
'fields': self.CONSTANTS.CLONE_FIELDS.UX_SCREEN
};
var screenPayload = {
'name': subPage.NAME,
'macroponent': newMacroponentId,
'app_config': appConfig,
'screen_type': newScreenTypeId,
'parent_macroponent': appContentBlockId
};
self.GLOBAL._grRecordCreator(self.UXF_TABLE.SCREEN, screenPayload, screenCloneInfo);
},
_patchScreenCollectionToRoute: function(subPage, appContentBlockId, appConfig, newScreenTypeId) {
var self = this;
var route_gr = new GlideRecord(self.UXF_TABLE.APP_ROUTE);
route_gr.addQuery('route_type', subPage.ROUTE);
route_gr.addQuery('parent_macroponent', appContentBlockId);
route_gr.addQuery('app_config', appConfig);
route_gr.query();
if (route_gr.next()) {
var route_id = route_gr.sys_id;
self.GLOBAL.updateRecord(self.UXF_TABLE.APP_ROUTE, route_id, {
'screen_type': newScreenTypeId
});
}
},
_cloneMacroponentAndScripts: function(baseMacroponent, subPageName, appContentBlockId) {
var self = this;
// MACROPONENT CREATION
var newMacroponentGr = self._cloneMacroponentForSubpage(baseMacroponent, subPageName, appContentBlockId);
if (!newMacroponentGr) {
return;
}
var newMacroponentSysId = newMacroponentGr.getValue('sys_id');
// CLONE CLIENT SCRIPTS
var clientScriptMaps = self._cloneClientScripts(baseMacroponent, newMacroponentSysId);
// POST UPDATE MACROPONENT
self._updateNewMacroponentWithScripts(newMacroponentGr, clientScriptMaps, newMacroponentSysId);
return newMacroponentSysId;
},
cloneSubPages: function(appName, appConfig, appContentBlockId, subPages) {
// TODO: appName is not used in this method but do not remove it here unless you are going to refactor the
// various callers using this method signature through UIB/UX tranform script, etc.
var self = this;
try {
subPages.forEach(function(subPage) {
if (!subPage) {
return;
}
// OPTIONAL MACROPONENT CREATION
var newMacroponentId = subPage.MACROPONENT; // initialize to base macroponent
if (subPage.CLONE_MACROPONENT) {
newMacroponentId = self._cloneMacroponentAndScripts(subPage.MACROPONENT, subPage.NAME, appContentBlockId);
}
//SCREEN_TYPE CREATION
var newScreenTypeId = self._createScreenTypeForSubPage(subPage);
//SCREEN CREATION
self._createScreenForSubPage(subPage, newMacroponentId, appConfig, newScreenTypeId, appContentBlockId);
// PATCH SCREEN COLLECTION TO ROUTE
self._patchScreenCollectionToRoute(subPage, appContentBlockId, appConfig, newScreenTypeId);
});
} catch (e) {
gs.error("ACEAppBuilderUtil: Failed to create content block subpages: " + e.toString());
}
},
fixMissingSubPages: function(aceBaseCbSubpages, appCbSubpages, appContentBlockId, appConfigSysId) {
try {
var self = this;
var appSubpagesMap = {};
for (var i = 0; i < appCbSubpages.length; i++) {
appSubpagesMap[appCbSubpages[i].ROUTE] = appCbSubpages[i];
}
var subpagesWithMissingMacroponent = aceBaseCbSubpages.filter(function(baseSubpage) {
var appSubpage = appSubpagesMap[baseSubpage.ROUTE];
if (!appSubpage) {
return false;
}
// for subpages that are flagged to have their macroponents cloned,
// if both base and app subpage point to the same macroponent, then the macroponent is missing
return appSubpage.CLONE_MACROPONENT && baseSubpage.MACROPONENT === appSubpage.MACROPONENT;
});
subpagesWithMissingMacroponent.forEach(function(baseSubpage) {
var newMacroponentId = self._cloneMacroponentAndScripts(baseSubpage.MACROPONENT, baseSubpage.NAME, appContentBlockId);
var appSubpage = appSubpagesMap[baseSubpage.ROUTE];
appSubpage.MACROPONENT = newMacroponentId;
self.syncScreenWithBase(baseSubpage, appSubpage, appConfigSysId);
});
} catch (e) {
gs.error('ACEAppBuilderUtil: Failed to fix missing content block subpages: ' + e.toString());
}
},
getPropertiesPayload: function(propertyIds) {
var supportedTypes = this.CONSTANTS.SUPPORTED_PROPERTIES_TYPES;
return this.GLOBAL.getPropertiesPayload(propertyIds, supportedTypes);
},
getControlCardQuery: function(table) {
//Example query: name=incident^internal_type=string^ORinternal_type=string_full_utf8^ORinternal_type=integer^ORinternal_type=choice^ORinternal_type=boolean
var query = 'name=' + table + '^';
var supportedFields = this.CONSTANTS.SUPPORTED_PROPERTIES_TYPES;
query += supportedFields.map(function(f, index) {
return (index > 0 ? '^OR' : '') + 'internal_type=' + f;
}).join('');
return query;
},
getAnalyticsCardQuery: function(tableName) {
var query = 'name=' + tableName + '^';
var tableGr = new GlideRecord('sys_db_object');
tableGr.addQuery('name', tableName);
tableGr.query();
if (tableGr.next()) {
var superClass = tableGr.getValue('super_class');
if (superClass) {
var superClassTableGr = new GlideRecord('sys_db_object');
if (superClassTableGr.get(superClass)) {
query += 'OR' + 'name=' + superClassTableGr.getValue('name') + '^';
}
}
}
query += 'internal_type!=collection^ORinternal_type=NULL';
return query;
},
getControl: function(contentBlockPayload) {
var result = [];
var _self = this;
try {
contentBlockPayload.forEach(function(control) {
if (!control.props_details) {
return;
}
var controlType = control.props_details.control_type;
if (controlType === 'button') {
var buttonLabel = control.props_details.button_label;
var buttonEventName = control.props_details.button_event_name;
var payload = {
'title': control.title,
'subtitle': control.subtitle,
'type': control.props_details.control_type,
'button_data': {
label: buttonLabel,
event_name: buttonEventName
}
};
result.push(payload);
} else if (controlType === 'record') {
if (control.props_details.table && control.props_details.record && control.props_details.field) {
var table = control.props_details.table;
var recordId = control.props_details.record;
var fieldName = control.props_details.field;
var helperText = control.props_details.helper_text;
var placeHolderText = control.props_details.placeholder_text || '';
var isDisabled = (control.props_details.disabled === true);
var payload = {
'title': control.title,
'subtitle': control.subtitle,
'type': control.props_details.control_type,
'record_data': {}
};
if (fieldName) {
payload.record_data.field_name = fieldName;
var recordDetails = _self.GLOBAL.getRecord(table, recordId, [payload.record_data.field_name]);
if (recordDetails[payload.record_data.field_name] != undefined) {
payload.record_data.field_type = recordDetails.__internal_type;
payload.record_data.sys_id = recordId;
payload.record_data.table = table;
payload.record_data.old_value = recordDetails[payload.record_data.field_name];
payload.record_data.read_only = isDisabled || !(recordDetails.__canWrite && recordDetails.__isInSelectedScope);
if (helperText) {
payload.record_data.helper_text = helperText;
}
if (placeHolderText) {
payload.record_data.placeholder_text = placeHolderText;
}
if (recordDetails.__choices)
payload.record_data.choices = recordDetails.__choices;
}
}
result.push(payload);
}
}
});
return result;
} catch (e) {
return result;
}
},
_updateRecord: function(table, recordId, input) {
try {
return this.GLOBAL.updateRecord(table, recordId, input);
} catch (e) {
gs.error('ACEAppBuilderUtil: Error: ' + e.toString());
return false;
}
},
setControl: function(payload) {
try {
var updated = true,
_self = this;
for (var recordId in payload) {
var record = payload[recordId];
if (record.new_value != record.old_value) {
var input = {};
input[record.field_name] = record.new_value;
updated = _self._updateRecord(record.table, recordId, input) && updated;
}
}
return updated;
} catch (e) {
return false;
}
},
createAiSearchConfig: function(appConfigId, searchConfigBlockId) {
var searchSourceId, searchProfileId, searchApplicationId, appName, searchContextContentBlockId;
//fetching app name
if (!this.CAN_READ) return 3;
var gr = new GlideRecord(this.TABLE.APP_CONFIG);
if (gr.get(appConfigId)) {
appName = gr.getValue('name');
}
if (this.GLOBAL._isAisEnabled()) {
var dataSource = this.GLOBAL._grGetKeyDataFromTable('ais_datasource', this.AIS.searchIndex, 'source');
if (!this.GLOBAL.AISAlreadyExists(appName)) {
if (dataSource != null) {
searchSourceId = this.GLOBAL._grRecordCreator('ais_search_source', {
'name': appName + this.AIS.source,
'datasource': dataSource,
'condition': 'ace_config=' + appConfigId + ''
}, null, true);
}
if (searchSourceId != null) {
searchProfileId = this.GLOBAL._grRecordCreator('ais_search_profile', {
'label': appName + this.AIS.profile
}, null, true);
//map search source to profile
this.GLOBAL._grRecordCreator('ais_search_profile_ais_search_source_m2m', {
'profile': searchProfileId,
'search_source': searchSourceId
});
//publishing search profile
var searchProfileName = this.GLOBAL._grGetKeyDataFromTable('ais_search_profile', searchProfileId, 'name');
this.GLOBAL._aisPublishProfile(searchProfileName);
}
//creating search application
if (searchProfileId != null) {
searchApplicationId = this.GLOBAL._grRecordCreator('sys_search_context_config', {
'name': appName + this.AIS.application,
'search_profile': searchProfileId,
'genius_results_limit': 3
}, null, true);
}
// creating search context block
if (searchApplicationId != null) {
searchContextContentBlockId = this._grRecordCreator(this.TABLE.CONTENT_BLOCK, {
'type': this.CONSTANTS.CONTENT_BLOCK_TYPES.SEARCH_CONTEXT,
'name': appName + ' - Default Search Context',
'ace_config': appConfigId,
'parent': searchConfigBlockId,
'order': 10,
'document_id': appConfigId,
'document_table': this.TABLE.APP_CONFIG
});
this._setGlideVars(this.TABLE.CONTENT_BLOCK, searchContextContentBlockId, {
'search_application': searchApplicationId,
'evam_configuration': this.AIS.evam_config
});
}
if (searchContextContentBlockId != null) {
return 2;
}
} else {
return 1;
}
} else {
//zing search configuration
return 0;
}
return 3;
},
fetchRouteSearchResult: function(aceAppId, contentBlockId) {
var _self = this;
if (!this.CAN_READ) return null;
var contentBlockGr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
if (contentBlockGr.get(contentBlockId)) {
if (contentBlockGr.getValue('document_table') == this.TABLE.PAGE) {
var pageId = contentBlockGr.getValue('document_id');
var gr = new GlideRecord(this.TABLE.PAGE);
if (gr.get(pageId)) {
var routeId = gr.getValue('route');
var route = this.GLOBAL._grGetKeyDataFromTable(_self.UXF_TABLE.APP_ROUTE, routeId, 'route_type');
return getURL(aceAppId, route);
}
} else {
return getURL(aceAppId, '');
}
}
function getURL(aceAppId, route) {
var gr = new GlideRecord(_self.TABLE.APP_CONFIG);
var url = '';
if (gr.get(aceAppId)) {
url = '/now/' + _self.getURLPath(gr.getValue('app_config')) + '/' + route;
}
return url;
}
},
fetchSearchConfig: function(aceAppId) {
var _self = this;
function getURL(route, contentBlockId) {
var gr = new GlideRecord(_self.TABLE.APP_CONFIG);
var url = '';
if (gr.get(aceAppId)) {
url = '/now/' + _self.getURLPath(gr.getValue('app_config')) + '/' + route + '/' + contentBlockId;
}
return url;
}
var result = {};
if (!this.CAN_READ) return result;
var searchConfigBlocks = this._getContentBlocks('', {
'document_table': this.TABLE.APP_CONFIG,
'document_id': aceAppId,
'type': this.CONSTANTS.CONTENT_BLOCK_TYPES.SEARCH_CONFIG
});
if (searchConfigBlocks.length > 0) {
var pageId = searchConfigBlocks[0].props_details.page;
var gr = new GlideRecord(this.TABLE.PAGE);
if (gr.get(pageId)) {
var routeId = gr.getValue('route');
var route = this.GLOBAL._grGetKeyDataFromTable(_self.UXF_TABLE.APP_ROUTE, routeId, 'route_type');
result = {
page_route: route,
mode: searchConfigBlocks[0].props_details.mode,
sys_id: searchConfigBlocks[0].block_id,
url: getURL(route, searchConfigBlocks[0].block_id)
};
}
return result;
}
},
getSearchContexts: function(aceAppId, searchConfigContentBlockId) {
var result = [];
if (!this.CAN_READ) return result;
var searchContexts = this._getContentBlocks(searchConfigContentBlockId, {
'ace_config': aceAppId,
'type': this.CONSTANTS.CONTENT_BLOCK_TYPES.SEARCH_CONTEXT
});
searchContexts.forEach(function(context) {
if (context.props_details.evam_configuration && context.props_details.search_application) {
result.push({
'search_config': context.props_details.search_application,
'evam_config': context.props_details.evam_configuration
});
}
});
return result;
},
activateSearchConfig: function(aceAppId, searchConfigContentBlockId) {
var result = this.getSearchContexts(aceAppId, searchConfigContentBlockId);
if (result.length > 0) {
var gr = new GlideRecord(this.TABLE.CONTENT_BLOCK);
if (gr.get(searchConfigContentBlockId) && gr.canWrite()) {
gr.setValue('active', true);
gr.update();
return true;
}
}
return false;
},
getSubPageRoutes: function(appConfig, contentBlockId, appName) {
var self = this;
var routes = [];
var clone_macroponent_routes = self.CONSTANTS.CLONE_ROUTES;
var contentBlockGr = new GlideRecord(self.UXF_TABLE.APP_ROUTE);
contentBlockGr.addQuery('app_config', appConfig);
contentBlockGr.addQuery('parent_macroponent', contentBlockId);
contentBlockGr.query();
while (contentBlockGr.next()) {
var cloneMacroponent = clone_macroponent_routes.some(function(route) {
return route === contentBlockGr.getValue('route_type');
});
var screen_gr = new GlideRecord(self.UXF_TABLE.SCREEN);
screen_gr.addQuery('screen_type', contentBlockGr.getValue('screen_type'));
screen_gr.orderBy('sys_created_on');
screen_gr.setLimit(1);
screen_gr.query();
while (screen_gr.next()) {
var screen_id = screen_gr.getValue('sys_id');
}
screen_gr.get('screen_type', contentBlockGr.getValue('screen_type'));
routes.push({
MACROPONENT: screen_gr.getValue('macroponent'),
SCREEN: screen_id,
SCREEN_TYPE: contentBlockGr.getValue('screen_type'),
NAME: appName + " - " + contentBlockGr.getValue('name'),
ROUTE: contentBlockGr.getValue('route_type'),
ROUTE_ID: contentBlockGr.getValue('sys_id'),
VIEWPORT_ID: contentBlockGr.getValue('parent_macroponent_composition_element_id'),
CLONE_MACROPONENT: cloneMacroponent
});
}
return routes;
},
getClientScriptDetails: function(macroponentSysId) {
var client_scripts = [];
var client_script_gr = new GlideRecord('sys_ux_client_script');
client_script_gr.addQuery('macroponent', macroponentSysId);
client_script_gr.query();
while (client_script_gr.next()) {
client_scripts.push({
sys_id: client_script_gr.getValue('sys_id').toString(),
name: client_script_gr.getValue('name').toString(),
script: client_script_gr.getValue('script').toString(),
macroponent_id: macroponentSysId
});
}
return client_scripts;
},
getAppConfigDetails: function(aceAppConfig) {
if (!this.CAN_READ) return {};
var app_config_gr = new GlideRecord('sn_ace_app_config');
if (app_config_gr.get(aceAppConfig)) {
return {
app_config: app_config_gr.getValue('app_config').toString(),
context: JSON.parse(app_config_gr.getValue('context')),
app_name: app_config_gr.getValue('name')
};
}
},
syncNewSubPages: function(appName, aceBaseCbRoutes, appCbRoutes, appConfig) {
var self = this;
var content_block_id = appConfig.context.content_block_id;
var routes_diff = aceBaseCbRoutes.filter(function(acebase_route) {
return !appCbRoutes.some(function(route) {
return acebase_route.ROUTE === route.ROUTE;
});
});
routes_diff.forEach(function(route) {
var cloneInfo = {
'sys_id': route.ROUTE_ID,
'fields': self.CONSTANTS.CLONE_FIELDS.APP_ROUTE
};
var payload = {
'name': route.NAME,
'app_config': appConfig.app_config,
'parent_macroponent': content_block_id,
'parent_macroponent_composition_element_id': route.VIEWPORT_ID
};
self.GLOBAL._grRecordCreator(self.UXF_TABLE.APP_ROUTE, payload, cloneInfo);
});
self.cloneSubPages(appName, appConfig.app_config, content_block_id, routes_diff);
},
syncClientScriptsWithBase: function(aceBaseCbSubpage, appCbSubpage) {
var self = this;
var ace_base_client_scripts = self.getClientScriptDetails(aceBaseCbSubpage.MACROPONENT);
var app_client_scripts = self.getClientScriptDetails(appCbSubpage.MACROPONENT);
app_client_scripts.forEach(function(app_client_script) {
var ace_base_client_script = ace_base_client_scripts.filter(function(ace_base_client_script) {
return ace_base_client_script.name === app_client_script.name;
});
if (ace_base_client_script.length > 0) {
self.GLOBAL.updateRecord(self.UXF_TABLE.CLIENT_SCRIPT, app_client_script.sys_id, {
'script': ace_base_client_script[0].script
});
}
});
//Fetch client scripts that are part of a subpage in ace base content block and do not exist in app's content block su page
var client_script_diff = ace_base_client_scripts.filter(function(ace_base_client_script) {
return !app_client_scripts.some(function(app_client_script) {
return ace_base_client_script.name === app_client_script.name;
});
});
if (client_script_diff.length > 0) {
var macroponent = {};
var macroponent_gr = new GlideRecord(self.UXF_TABLE.MACROPONENT);
if (macroponent_gr.get(appCbSubpage.MACROPONENT)) {
macroponent.composition = macroponent_gr.getValue('composition'),
macroponent.data = macroponent_gr.getValue('data'),
macroponent.state_properties = macroponent_gr.getValue('state_properties'),
macroponent.internal_event_mappings = macroponent_gr.getValue('internal_event_mappings');
}
client_script_diff.forEach(function(client_script) {
var client_script_id = self.GLOBAL._grRecordCreator(self.UXF_TABLE.CLIENT_SCRIPT, {
'macroponent': appCbSubpage.MACROPONENT,
'name': client_script.name,
'script': client_script.script,
});
macroponent.composition = self._replaceAll(macroponent.composition, client_script.sys_id, client_script_id);
macroponent.data = self._replaceAll(macroponent.data, client_script.sys_id, client_script_id);
macroponent.state_properties = self._replaceAll(macroponent.state_properties, client_script.sys_id, client_script_id);
macroponent.internal_event_mappings = self._replaceAll(macroponent.internal_event_mappings, client_script.sys_id, client_script_id);
});
self.GLOBAL.updateRecord(self.UXF_TABLE.MACROPONENT, appCbSubpage.MACROPONENT, {
'composition': macroponent.composition,
'data': macroponent.data,
'state_properties': macroponent.state_properties,
'internal_event_mappings': macroponent.internal_event_mappings,
});
}
},
syncMacroponentWithBase: function(aceBaseCbSubpage, appCbSubpage, appConfig) {
var self = this;
var macroponent = {};
var ace_base_macroponent_gr = new GlideRecord(self.UXF_TABLE.MACROPONENT);
if (ace_base_macroponent_gr.get(aceBaseCbSubpage.MACROPONENT)) {
macroponent.composition = ace_base_macroponent_gr.getValue('composition'),
macroponent.data = ace_base_macroponent_gr.getValue('data'),
macroponent.layout = ace_base_macroponent_gr.getValue('layout'),
macroponent.properties = ace_base_macroponent_gr.getValue('props'),
macroponent.state_properties = ace_base_macroponent_gr.getValue('state_properties'),
macroponent.internal_event_mappings = ace_base_macroponent_gr.getValue('internal_event_mappings'),
macroponent.dispatched_events = ace_base_macroponent_gr.getValue('dispatched_events'),
macroponent.handled_events = ace_base_macroponent_gr.getValue('handled_events');
}
macroponent.composition = self._replaceAll(macroponent.composition, self.CONSTANTS.BASE_UXF_RECORDS.CONTENT_BLOCK.MACROPONENT, appConfig.context.content_block_id);
var ace_base_client_scripts = self.getClientScriptDetails(aceBaseCbSubpage.MACROPONENT);
var app_client_scripts = self.getClientScriptDetails(appCbSubpage.MACROPONENT);
app_client_scripts.forEach(function(app_client_script) {
var client_script = ace_base_client_scripts.filter(function(ace_base_client_script) {
return app_client_script.name === ace_base_client_script.name;
});
if (client_script.length > 0) {
macroponent.composition = self._replaceAll(
macroponent.composition,
client_script[0].sys_id,
app_client_script.sys_id
);
macroponent.data = self._replaceAll(
macroponent.data,
client_script[0].sys_id,
app_client_script.sys_id
);
macroponent.state_properties = self._replaceAll(
macroponent.state_properties,
client_script[0].sys_id,
app_client_script.sys_id
);
macroponent.internal_event_mappings = self._replaceAll(
macroponent.internal_event_mappings,
client_script[0].sys_id,
app_client_script.sys_id
);
}
});
self.GLOBAL.updateRecord(self.UXF_TABLE.MACROPONENT, appCbSubpage.MACROPONENT, {
'composition': macroponent.composition,
'data': macroponent.data,
'layout': macroponent.layout,
'props': macroponent.properties,
'state_properties': macroponent.state_properties,
'internal_event_mappings': macroponent.internal_event_mappings,
'dispatched_events': macroponent.dispatched_events,
'handled_events': macroponent.handled_events
});
},
syncRouteWithBase: function(aceBaseCbSubpage, appCbSubpage, appConfig) {
var self = this;
var route = {};
var ace_base_route_gr = new GlideRecord(self.UXF_TABLE.APP_ROUTE);
if (ace_base_route_gr.get(aceBaseCbSubpage.ROUTE_ID)) {
route.name = ace_base_route_gr.getValue('name'),
route.fields = ace_base_route_gr.getValue('fields'),
route.optional_parameters = ace_base_route_gr.getValue('optional_parameters'),
route.parent_macroponent_composition_element_id = ace_base_route_gr.getValue('parent_macroponent_composition_element_id');
}
self.GLOBAL.updateRecord(self.UXF_TABLE.APP_ROUTE, appCbSubpage.ROUTE_ID, {
'name': appConfig.app_name + "-" + route.name,
'parent_macroponent': appConfig.context.content_block_id,
'fields': route.fields,
'optional_parameters': route.optional_parameters,
'parent_macroponent_composition_element_id': route.parent_macroponent_composition_element_id,
'screen_type': appCbSubpage.SCREEN_TYPE,
'app_config': appConfig.app_config,
});
},
syncScreenWithBase: function(aceBaseCbSubpage, appCbSubpage, appConfig) {
var self = this;
var screen = {};
var ace_base_screen_gr = new GlideRecord(self.UXF_TABLE.SCREEN);
if (ace_base_screen_gr.get(aceBaseCbSubpage.SCREEN)) {
var content_block_routes_gr = new GlideRecord(self.UXF_TABLE.APP_ROUTE);
content_block_routes_gr.addQuery('app_config', self.CONSTANTS.BASE_UXF_RECORDS.ACE_BASE_EXPERIENCE_APP_CONFIG);
content_block_routes_gr.addQuery('parent_macroponent', self.CONSTANTS.BASE_UXF_RECORDS.CONTENT_BLOCK.MACROPONENT);
content_block_routes_gr.addQuery('screen_type', ace_base_screen_gr.getValue('screen_type'));
content_block_routes_gr.query();
if (!content_block_routes_gr.next())
return;
screen.name = appConfig.app_name + ' - ' + content_block_routes_gr.getValue('name');
screen.macroponent_config = ace_base_screen_gr.getValue('macroponent_config');
screen.event_mappings = ace_base_screen_gr.getValue('event_mappings');
screen.page_definition = (appCbSubpage.CLONE_MACROPONENT) ? appCbSubpage.MACROPONENT : aceBaseCbSubpage.MACROPONENT;
}
self.GLOBAL.updateRecord(self.UXF_TABLE.SCREEN, appCbSubpage.SCREEN, {
'name': screen.name,
'screen_type': appCbSubpage.SCREEN_TYPE,
'macroponent': screen.page_definition,
'parent_macroponent': appConfig.context.content_block_id,
'macroponent_config': screen.macroponent_config,
'event_mappings': screen.event_mappings,
'app_config': appConfig.app_config
});
},
hardSyncWithBase: function(aceAppConfig) {
var self = this;
var app_config = self.getAppConfigDetails(aceAppConfig);
var app_name = app_config.app_name;
var app_content_block_id = app_config.context.content_block_id;
var ace_base_cb_subpages = self.getSubPageRoutes(self.CONSTANTS.BASE_UXF_RECORDS.ACE_BASE_EXPERIENCE_APP_CONFIG, self.CONSTANTS.BASE_UXF_RECORDS.CONTENT_BLOCK.MACROPONENT, app_name);
var app_cb_subpages = self.getSubPageRoutes(app_config.app_config, app_content_block_id, app_name);
self.syncNewSubPages(app_name, ace_base_cb_subpages, app_cb_subpages, app_config);
app_cb_subpages.forEach(function(subpage) {
var ace_base_cb_subpage = ace_base_cb_subpages.filter(function(acebase_subpage) {
return acebase_subpage.ROUTE === subpage.ROUTE;
});
if (ace_base_cb_subpage.length > 0) {
if (subpage.CLONE_MACROPONENT) {
self.syncMacroponentWithBase(ace_base_cb_subpage[0], subpage, app_config);
self.syncClientScriptsWithBase(ace_base_cb_subpage[0], subpage);
}
self.syncRouteWithBase(ace_base_cb_subpage[0], subpage, app_config);
self.syncScreenWithBase(ace_base_cb_subpage[0], subpage, app_config);
}
});
self.fixMissingSubPages(ace_base_cb_subpages, app_cb_subpages, app_content_block_id, app_config.app_config);
//sync content block macroponent and client scripts
self.syncMacroponentWithBase({
MACROPONENT: self.CONSTANTS.BASE_UXF_RECORDS.CONTENT_BLOCK.MACROPONENT
}, {
MACROPONENT: app_content_block_id
}, app_config);
self.syncClientScriptsWithBase({
MACROPONENT: self.CONSTANTS.BASE_UXF_RECORDS.CONTENT_BLOCK.MACROPONENT
}, {
MACROPONENT: app_content_block_id
});
},
hasReadAccess: function() {
return gs.hasRole('sn_ace.ace_user');
},
type: 'ACEAppBuilderUtil'
};
Sys ID
a36948529d373410f8776ab43f397e99