<#ftl output_format="JSON"> <#-- Defines the metadata for the generating all design objects supported by the Object Template Framework. This recipe should be used as a template and for demo only. DON"T expose it to the customer throug the template registry. The request to the Template Recipe Service must include the following: 1) TARGET OBJECT: the record type and user selected related record types this recipe is used for 2) TARGET APPLICATION: the application this recipe applies to 3) ADDITIONAL METADATA: data specific to this recipe a) viewName: user inputted name for new record view b) suggestedInferenceMap: rule to infer the last used RULE_FOLDER --> <#-- Object trigger macros --> <#import "/recipes/v2/triggers/triggerUtility_v2.ftl" as triggerUtility> <#import "/recipes/v2/triggers/ruleFolderTrigger_v2.ftl" as ruleFolderTrigger> <#import "/recipes/v2/triggers/groupTrigger_v2.ftl" as groupTrigger> <#import "/recipes/v2/triggers/interfaceTrigger_v2.ftl" as interfaceTrigger> <#import "/recipes/v2/triggers/recordTypeTrigger_v2.ftl" as recordTypeTrigger> <#import "/recipes/v2/triggers/siteTrigger_v2.ftl" as siteTrigger> <#import "/recipes/v2/triggers/connectedSystemTrigger_v2.ftl" as connectedSystemTrigger> <#import "/recipes/v2/triggers/tempoReportTrigger_v2.ftl" as tempoReportTrigger> <#import "/recipes/v2/triggers/taskReportTrigger_v2.ftl" as taskReportTrigger> <#import "/recipes/v2/triggers/dataStoreTrigger_v2.ftl" as dataStoreTrigger> <#import "/recipes/v2/triggers/constantTrigger_v2.ftl" as constantTrigger> <#import "/recipes/v2/triggers/integrationTrigger_v2.ftl" as integrationTrigger> <#import "/recipes/v2/triggers/decisionTrigger_v2.ftl" as decisionTrigger> <#-- Objects are used in the Forward Flow features --> <#import "/recipes/v2/objectConfigurationHelper_v2.ftl" as objectConfigurationHelper> <#import "/recipes/v2/interfaceHelper_v2.ftl" as interfaceHelper> <#assign textResolver = request.getTextResolver()> <#assign viewName = textResolver.format(request.additionalMetadata.viewName, "PASCAL_CASE", "")> <#assign userGroupUuid = request.generateUuid("USER_GROUP")> <#assign userGroupRecipeId = "GROUP-0"> <#assign adminGroupUuid = request.generateUuid("ADMIN_GROUP")> <#assign adminGroupRecipeId = "GROUP-1"> <#assign ruleFolderUuid = request.generateUuid("RULE_FOLDER")> <#assign ruleFolderRecipeId = "RULE_FOLDER-0"> <#assign interfaceRecipeId = "INTERFACE-0"> <#-- Objects are NOT used in the Forward Flow features --> <#import "/recipes/v2/connectedSystemHelper_v2.ftl" as connectedSystemHelper> <#import "/recipes/v2/constantHelper_v2.ftl" as constantHelper> <#import "/recipes/v2/decisionHelper_v2.ftl" as decisionHelper> <#import "/recipes/v2/integrationHelper_v2.ftl" as integrationHelper> <#import "/recipes/v2/recordTypeHelper_v2.ftl" as recordTypeHelper> <#import "/recipes/v2/reportHelper_v2.ftl" as reportHelper> <#import "/recipes/v2/siteHelper_v2.ftl" as siteHelper> <#assign connectedSystemRecipeId_0 = "CONNECTED_SYSTEM-0"> <#assign connectedSystemUuid_0 = request.generateUuid("CONNECTED_SYSTEM")> <#assign constantRecipeId = "CONSTANT-0"> <#assign decisionRecipeId = "DECISION-0"> <#assign integrationRecipeId = "INTEGRATION-0"> <#assign recordRecipeId = "RECORD_TYPE-0"> <#assign siteRecipeId = "SITE-0"> <#assign taskReportRecipeId = "TASK_REPORT-0"> <#assign tempoReportRecipeId = "TEMPO_REPORT-0"> <#-- Objects are used in the legacy Forward Flow features --> <#import "/recipes/v2/dataStoreHelper_v2.ftl" as dataStoreHelper> <#import "/recipes/v2/dataTypeHelper_v2.ftl" as dataTypeHelper> <#assign dseConstantRecipeId = "CONSTANT-1"> <#global globalDataStoreEntityUuid = request.generateUuid("DATASTORE_ENTITY")> <#assign dataStoreRecipeId = "DATASTORE-0"> <#global globalDataStoreUuid = request.generateUuid("DATASTORE")> <#assign dataTypeRecipeId = "DATATYPE-0"> <#assign dataTypeName = request.formatDesignObjectName("DATATYPE", "_", textResolver.format(request.getTargetObjectNameWithoutPrefix(), "PASCAL_CASE", "Record")) > <#assign dataTypeNamespace = textResolver.format("urn:com:appian:types", "JOIN", ":", request.getAppPrefix())> { <#-- The section covers the initial recipe settings --> "version": 2, "id": "CREATE_ALL_OBJECTS_DEMO", "summaryTitle": "${request.getTextWithKey("recordViewTemplateRecipe.summaryTitle")?json_string}", "summaryObjectStatsInstructions": "${request.getTextWithKey("recordViewTemplateRecipe.objectStatsInstructions")?json_string}", "summaryCreateObjectsInstructions": "${request.getTextWithKey("recordViewTemplateRecipe.createObjectsInstructions")?json_string}", <#-- The UI model section which defines the skeleton of the Forward Flow wizard presenting and managing recipe metadata of design objects this wizard creates or updates. --> "uiModel":[ { "name": "${request.getTextWithKey("recordViewTemplateRecipe.objectGroupInfos.interface.name")?json_string}", "description": "${request.getTextWithKey("recordViewTemplateRecipe.object.interface.description")?json_string}", "link": "links.docs.forwardflow.view.interface", "icon": "interface", "recipeObjectIds": [ "${interfaceRecipeId}" ] }, { "name": "${request.getTextWithKey("recordActionTemplateRecipe.objectGroupInfos.data.name")}", "description": "${request.getTextWithKey("recordActionTemplateRecipe.objectGroupInfos.data.description")}", "link":"links.docs.forwardflow.data", "icon":"database", "recipeObjectIds":[ "${dataTypeRecipeId}", "${dataStoreRecipeId}", "${dseConstantRecipeId}" ] }, { "name": "Not Used Supported Objects", "description": "This section includes all suppoprted design objects currently are NOT used in any Forward Flow Feature", "link": "N/A", "icon": "wrench", "recipeObjectIds": [ "${connectedSystemRecipeId_0}", "${integrationRecipeId}", "${constantRecipeId}", "${recordRecipeId}", "${tempoReportRecipeId}", "${taskReportRecipeId}", "${siteRecipeId}", "${decisionRecipeId}" ] }, { "name": "${request.getTextWithKey("recordActionTemplateRecipe.objectGroupInfos.secAndOrg.name")?json_string}", "description": "${request.getTextWithKey("recordActionTemplateRecipe.objectGroupInfos.secAndOrg.description")?json_string}", "link": "links.docs.forwardflow.securityAndOrganization", "icon": "lock", "recipeObjectIds": [ "${adminGroupRecipeId}", "${userGroupRecipeId}", "${ruleFolderRecipeId}" ] } ], <#-- The biz model section defines design objects created or updated from this initial recipe metadata --> "bizModel":{ "GROUP":[ <#assign userTriggers> [ { <@triggerUtility.selectObject recipeObjectId=userGroupRecipeId objectType="GROUP" /> "targets": [ <@ruleFolderTrigger.updateReaderGroups recipeObjectId=ruleFolderRecipeId />, <@siteTrigger.updateViewerGroups recipeObjectId=siteRecipeId />, <@connectedSystemTrigger.updateReaderGroups recipeObjectId=connectedSystemRecipeId_0 />, <@recordTypeTrigger.updateReaderGroups recipeObjectId=recordRecipeId />, <@tempoReportTrigger.updateViewerGroups recipeObjectId=tempoReportRecipeId />, <@taskReportTrigger.updateViewerGroups recipeObjectId=taskReportRecipeId />, <@dataStoreTrigger.updateReaderGroups recipeObjectId=dataStoreRecipeId /> ] } ] <#assign adminTriggers> [ { <@triggerUtility.selectObject recipeObjectId=adminGroupRecipeId objectType="GROUP" /> "targets": [ <@ruleFolderTrigger.updateAdminGroups recipeObjectId=ruleFolderRecipeId />, <@connectedSystemTrigger.updateAdminGroups recipeObjectId=connectedSystemRecipeId_0 />, <@recordTypeTrigger.updateAdminGroups recipeObjectId=recordRecipeId />, <@tempoReportTrigger.updateAdminGroups recipeObjectId=tempoReportRecipeId />, <@taskReportTrigger.updateAdminGroups recipeObjectId=taskReportRecipeId />, <@groupTrigger.updateAdminGroups recipeObjectId=userGroupRecipeId />, <@groupTrigger.updateMemberGroups recipeObjectId=userGroupRecipeId />, <@siteTrigger.updateAdminGroups recipeObjectId=siteRecipeId />, <@dataStoreTrigger.updateAdminGroups recipeObjectId=dataStoreRecipeId /> ] } ] <@objectConfigurationHelper.newAdminAndUserGroups request=request userGroupUuid=userGroupUuid adminGroupUuid=adminGroupUuid userTriggers=userTriggers adminTriggers=adminTriggers /> ], "RULE_FOLDER":[ <#assign triggers> [ { <@triggerUtility.selectObject recipeObjectId=ruleFolderRecipeId objectType="RULE_FOLDER" /> "targets": [ <@interfaceTrigger.updateParent recipeObjectId=interfaceRecipeId />, <@constantTrigger.updateParent recipeObjectId=constantRecipeId />, <@constantTrigger.updateParent recipeObjectId=dseConstantRecipeId />, <@decisionTrigger.updateParent recipeObjectId=decisionRecipeId />, <@integrationTrigger.updateParent recipeObjectId=integrationRecipeId /> ] }, { <@triggerUtility.selectVisibility recipeObjectId=ruleFolderRecipeId objectType="RULE_FOLDER" /> "targets": [ <@triggerUtility.updateVisibility recipeObjectId=userGroupRecipeId objectType="GROUP" />, <@triggerUtility.updateVisibility recipeObjectId=adminGroupRecipeId objectType="GROUP" /> ] } ] <@objectConfigurationHelper.newRuleFolder request=request ruleFolderUuid=ruleFolderUuid adminGroupUuid=adminGroupUuid userGroupUuid=userGroupUuid triggers=triggers /> ], "INTERFACE":[ <#assign formattedRecordName = textResolver.format(request.getTargetObjectNameWithoutPrefix(), "PASCAL_CASE", "") formattedViewName = viewName interfaceName = textResolver.format(request.getAppPrefix(), "REMOVE_SUFFIX", '_') + (request.getAppPrefix()?has_content)?string('_','') + formattedRecordName + (formattedRecordName?has_content && formattedViewName?has_content)?string('_','') + formattedViewName /> <#assign ruleInputs> [ { "name": "record", "typeName": "${request.getTargetObject().uuid}", "typeNamespace": "urn:com:appian:recordtype:datatype" } ] <@interfaceHelper.newInterface request=request recipeObjectId=interfaceRecipeId uuid=request.generateUuid("INTERFACE") name=(interfaceName?has_content)?string(interfaceName, '_') description=request.getTextWithKey("recordViewTemplateRecipe.object.interface.description") ruleInputs=ruleInputs ruleContents="/ix/v2/recordViews/recordViewInterfaceRuleContents_v2.ftlx" testInputs="/ix/v2/recordViews/recordViewInterfaceTestInputs_v2.ftlx" ruleFolderUuid=ruleFolderUuid/> ], "CONNECTED_SYSTEM":[ <#-- Example of Connected System to HTTP --> <#assign connectedSystemName0 = viewName + " SYSTEM HTTP"> <#assign sharedConfigParameters0 = { "templateHelper": "sharedConfigParameters/httpConfigurationDescriptor_v2.ftl", "authType": "None", <#-- TODO: request.additionalMetadata.authType --> "baseUrl": "https://chat.googleapis.com/v1/spaces" <#-- TODO: request.additionalMetadata.baseUrl --> }> <#assign triggers> [ { <@triggerUtility.selectObject recipeObjectId=connectedSystemRecipeId_0 objectType="CONNECTED_SYSTEM" /> "targets": [ <@integrationTrigger.updateConnectedSystem recipeObjectId=integrationRecipeId /> ] } ] <@connectedSystemHelper.newConnectedSystem request=request recipeObjectId=connectedSystemRecipeId_0 uuid=connectedSystemUuid_0 name=connectedSystemName0 description="Description for " + connectedSystemName0 integrationType="system.http" sharedConfigParameters=sharedConfigParameters0 adminGroups="[\"${adminGroupUuid}\"]" readerGroups="[\"${userGroupUuid}\"]" triggers=triggers/> ], "CONSTANT":[ <#assign constantName0 = viewName + " CONSTANT"> <@constantHelper.newConstant request=request recipeObjectId=constantRecipeId uuid=request.generateUuid("CONSTANT") name=constantName0 description="Description for " + constantName0 ruleFolderUuid=ruleFolderUuid typeName="int" typeNamespace="http://www.w3.org/2001/XMLSchema" value=1 isEnvironmentSpecific=true />, <@constantHelper.newConstant request=request recipeObjectId=dseConstantRecipeId uuid=request.generateUuid("CONSTANT") name=textResolver.format(request.getAppPrefix(), "REMOVE_SUFFIX", '_') + "_" + textResolver.format(request.getTargetObjectNameWithoutPrefix(), "UPPERCASE_UNDERSCORE", "Record") + "_DSE" description=request.getTextWithKey("recordActionTemplateRecipe.object.dseConstant.description", request.getTargetObjectNameWithoutPrefix()) ruleFolderUuid=ruleFolderUuid typeName="DataStoreEntity" typeNamespace="http://www.appian.com/ae/types/2009" designObjectConstantFile="designObjectConstants/dataStoreEntityConstant_v2.ftl" isEnvironmentSpecific=false /> ], "DATASTORE":[ <#assign triggers> [ { <@triggerUtility.selectObject recipeObjectId=dataStoreRecipeId objectType="DATASTORE" /> "targets": [ <@constantTrigger.updateDataStore recipeObjectId=dseConstantRecipeId /> ] } ] <#assign entities = [{ "uuid": globalDataStoreEntityUuid, "name": dataTypeName, "type": "{" + dataTypeNamespace + "}" + dataTypeName, "datatypeRecipeObjectId": dataTypeRecipeId, "dseObjectStatus": "NEW" }]/> <@dataStoreHelper.newDataStore request=request recipeObjectId=dataStoreRecipeId uuid=globalDataStoreUuid name=request.formatDesignObjectNameFromBundle("DATASTORE", "recordActionTemplateRecipe.object.dataStore.name.dataStore") description=request.getTextWithKey("recordActionTemplateRecipe.object.dataStore.description", request.application.name) adminGroups="[\"${adminGroupUuid}\"]" readerGroups="[\"${userGroupUuid}\"]" entities=entities triggers=triggers /> ], "DATATYPE":[ <#assign triggers> [ { <@triggerUtility.selectVisibility recipeObjectId=dataTypeRecipeId objectType="DATATYPE" /> "targets": [ <@triggerUtility.updateVisibility recipeObjectId=dataStoreRecipeId objectType="DATASTORE" />, <@triggerUtility.updateVisibility recipeObjectId=dseConstantRecipeId objectType="CONSTANT" /> ] } ] <@dataTypeHelper.newDataType request=request recipeObjectId=dataTypeRecipeId uuid=request.generateUuid("DATATYPE") name=dataTypeName description=request.getTextWithKey("recordActionTemplateRecipe.object.dataType.description.baseDataStructure", request.getTargetObjectNameWithoutPrefix()) typeNamespace=dataTypeNamespace triggers=triggers /> ], "INTEGRATION":[ <#assign integrationName = viewName + "IntegrationName"> <@integrationHelper.newIntegration request=request recipeObjectId=integrationRecipeId uuid=request.generateUuid("INTEGRATION") name=integrationName ruleFolderUuid=ruleFolderUuid connectedSystemUuid=connectedSystemUuid_0 description="Description for " + integrationName /> ], "RECORD_TYPE":[ <#assign recordName = viewName + "RecordTypeName"> <#assign recordPluralName = viewName + "RecordTypePluralName"> <#assign recordUrlStub = viewName + "RecordTypeUrlStub"> <#assign sourceRecordTypeFieldUuid=request.generateUuid("FIELD")> <#assign relationshipUuid=request.generateUuid("RELATIONSHIP")> <#assign fields> [ { "uuid": "${sourceRecordTypeFieldUuid}", "name": "id", "friendlyName": "Id", "sourceFieldType": "INTEGER", "sourceFieldName": "ID", "isRecordId": true, "isUnique": true, "qName": "{http://www.appian.com/ae/types/2009}Integer", "fieldRelationship": { "relationshipType": "MANY_TO_ONE", "relationshipName": "UserRelationship", "relationshipUuid": "${relationshipUuid}", "targetFieldUuid": "SYSTEM_RECORD_TYPE_USER_FIELD_username" } } ] <#assign relationships> [ { "uuid": "${relationshipUuid}", "name": "UserRelationship", "targetRecordTypeUuid": "SYSTEM_RECORD_TYPE_USER", "relationshipType": "MANY_TO_ONE", "sourceRecordTypeFieldUuid": "${sourceRecordTypeFieldUuid}", "targetRecordTypeFieldUuid": "SYSTEM_RECORD_TYPE_USER_FIELD_username", "fieldCfgUuid": "${request.generateUuid("FIELD_CFG")}", "targetRecordTypeName": "User" } ] <@recordTypeHelper.newRecordType request=request recipeObjectId=recordRecipeId uuid=request.generateUuid("RECORD_TYPE") name=recordName pluralName=recordPluralName description="Description for " + recordName urlStub=recordUrlStub tableName="RECORD_TYPE_TABLE_NAME" shouldCreateTable=false tableOrder=0 fields=fields?eval_json relationships=relationships?eval_json adminGroups=["${adminGroupUuid}"] readerGroups=["${userGroupUuid}"] /> ], "TEMPO_REPORT":[ <#assign tempoReportName = viewName + "TempoReportName"> <#assign tempoReportUrlStub = viewName + "TempoReportUrlStub"> <@reportHelper.newReport request=request recipeObjectId=tempoReportRecipeId objectType="TEMPO_REPORT" uuid=request.generateUuid("REPORT") name=tempoReportName description="Description for " + tempoReportName urlStub=tempoReportUrlStub <#-- this will be passed in through SAIL --> uiExpr="" adminGroups="[\"${adminGroupUuid}\"]" viewerGroups="[\"${userGroupUuid}\"]" /> ], "TASK_REPORT":[ <#assign taskReportName = viewName + "TaskReportName"> <#assign taskReportUrlStub = viewName + "TaskReportUrlStub"> <@reportHelper.newReport request=request recipeObjectId=taskReportRecipeId objectType="TASK_REPORT" uuid=request.generateUuid("REPORT") name=taskReportName description="Description for " + taskReportName urlStub=taskReportUrlStub <#-- this will be passed in through SAIL --> uiExpr="" adminGroups="[\"${adminGroupUuid}\"]" viewerGroups="[\"${userGroupUuid}\"]" /> ], "SITE":[ <#assign siteName = viewName + " Site"> <#assign siteDisplayName = "Display Name [" + siteName + "]"> <#assign sitePages> [ { "staticName": "Users", "description": "My Users", "urlStub": "users-page", "uiObjectUuid": "SYSTEM_RECORD_TYPE_USER", "uiObjectType": "a:RecordType", "iconId": "f2ba", "visibilityExpr": "fn!true()", "pageWidth": "WIDE" } ] <@siteHelper.newSite request=request recipeObjectId=siteRecipeId uuid=request.generateUuid("SITE") name=siteName description="Description for " + siteName urlStub= "urlStub" + viewName + "Site" <#-- this will be passed in request.additionalMetadata.siteUrlStub --> visibility="268435456" faviconRefUuid="SYSTEM_CONTENT_SITES_DEFAULT_FAVICON" faviconRefType="a:CollaborationDocument" logoRefUuid="SYSTEM_CONTENT_SITES_DEFAULT_LOGO" logoRefType="a:CollaborationDocument" showName="false" tempoLinkVisibility="HIDDEN" showRecordNews="true" tasksInSitesVisibility="HIDDEN" buttonShape="SQUARED" navigationBarStyle="STYLE1" inputShape="SQUARED" isSystem="false" displayName=siteDisplayName isStaticDisplayName="true" adminGroups="[\"${adminGroupUuid}\"]" viewerGroups="[\"${userGroupUuid}\"]" sitePages=sitePages /> ], "DECISION":[ <#-- Example of parameters to be passed to Decision--> <#assign decisionInputs> [ { "id": 1, "name": "input1", "typeName": "string", "typeNamespace": "{http://www.appian.com/ae/types/2009}Text", "restrictionType": "NONE" } ] <#assign decisionOutputs> [ { "id": 1, "name": "output1", "typeName": "{http://www.appian.com/ae/types/2009}Text", "returnListType": "false", "restrictionType": "NONE", "defaultValue": "NOT OK" } ] <#assign decisionRules> [ { "id": 1, "inputs": [ { "id": 1, "decisionInputId": 1, "operator": "EQUALS", "value": "sup" } ], "outputs": [ { "id": 1, "decisionOutputId": 1, "value": "OK" } ] } ] <#assign decisionName = viewName + "decisionName"> <#assign decisionIsUnqiue = "true"> <#assign decisionhitPolicy = "UNIQUE"> <@decisionHelper.newDecision request=request recipeObjectId=decisionRecipeId uuid=request.generateUuid("DECISION") name=decisionName description="Description for " + decisionName inputs=decisionInputs outputs=decisionOutputs rules=decisionRules isUnique=decisionIsUnqiue hitPolicy=decisionhitPolicy ruleFolderUuid=ruleFolderUuid/> ] } }