Name

sn_uibtk_api.Macroponent

Description

No description available

Script

const Macroponent = Class.create();
Macroponent.prototype = Object.extendsObject(BuilderToolkitAPIBase, {
  TABLE: 'sys_ux_macroponent',
  FIELDS: ["extends", "bundles", "composition", "data", "layout", "props", "handled_events", "dispatched_events", "internal_event_mappings", "root_component", "root_component_config", "root_component_definition", "associated_types", "category", "state_properties", "required_translations", "output_prop_mapping", "ext_controller_dep", "description", "extension_point", "name", "sys_policy"],

  /**
   * @param fields {string[]}
   */
  initialize: function(fields) {
      BuilderToolkitAPIBase.prototype.initialize.call(this, this.TABLE, fields || this.FIELDS, this.TRANSLATABLE_FIELDS);
  },

  /**
   * Overrides parent class function to inject special fields
   * @param acc {object} the accumulator object
   * @param field {GlideElement} the field element we are currently working on
   */
  getFieldValues: function(acc, field) {
      acc = BuilderToolkitAPIBase.prototype.getFieldValues.call(this, acc, field);
      if (field.nil()) {
          return acc;
      }
      const fieldName = field.getName();
      if (fieldName === 'root_component_config') {
          acc['rootComponentConfig'] = this.parseJSON(field, {
              field: 'root_component_config',
              sysId: acc.sysId
          });
      } else if (fieldName === 'root_component_definition') {
          acc['rootComponentDefinition'] = this.parseJSON(field, {
              field: 'root_component_definition',
              sysId: acc.sysId
          });
      }
      return acc;
  },

  /**
   * @param macroponentGR {GlideRecord} the record we are getting composition from
   */
  getCompositionMacroponentDefinitions: function(macroponentGR) {
      const composition = this.parseJSON(macroponentGR.composition, {
          field: 'composition',
          sysId: macroponentGR.sysId || macroponentGR.getUniqueValue()
      });
      if (composition && Array.isArray(composition)) {
          return this.getRecordsByQuery('sys_idIN' + macroponentGR.extends + ',' + this.getCompositionMacroponentIds(composition).join(','));
      }
  },

  /**
   * @param composition {UxElement[]} an array of elements
   */
  getCompositionMacroponentIds: function(composition) {
      const that = this;
      if (Array.isArray(composition)) {
          return composition.reduce(function(acc, element) {
              acc.push(element.definition.id);
              if (element.overrides && element.overrides.composition && element.overrides.composition.length > 0) {
                  return acc.concat(that.getCompositionMacroponentIds(element.overrides.composition));
              }
              return acc;
          }, []);
      }
  },

  /**
   * @param composition {UxElement[]} an array of elements
   */
  getCompositionReferenceIds: function(composition) {
      if (Array.isArray(composition)) {
          return composition.reduce(function(acc, element) {
              acc.mcpIds.push(element.definition.id);
              element.preset ? acc.presetIds.push(element.preset.id) : null;
              if (element.overrides && element.overrides.composition && element.overrides.composition.length > 0) {
                  const overrideValues = this.getCompositionReferenceIds(element.overrides.composition);
                  return {
                      mcpIds: acc.mcpIds.concat(overrideValues.mcpIds),
                      presetIds: acc.presetIds.concat(overrideValues.presetIds)
                  };
              }
              return acc;
          }.bind(this), {
              mcpIds: [],
              presetIds: []
          });
      }
      return {
          mcpIds: [],
          presetIds: []
      };
  },

  /**
   * @param composition {UxElement[]} an array of elements
   */
  getCompositionElements: function(composition) {
      const that = this;
      if (Array.isArray(composition)) {
          return composition.reduce(function(acc, element) {
              acc.push({
                  propertyValues: element.propertyValues || {},
                  elementLabel: element.elementLabel,
                  elementId: element.elementId,
                  macroponentType: null // See if this is actually needed, it's expensive
              });
              if (element.overrides && element.overrides.length > 0) {
                  return acc.concat(that.getCompositionElements(element.overrides));
              }
              return acc;
          }, []);
      }
  },

  /**
   * @param macroponentGR {GlideRecord} the record we are getting values from
   */
  getHierarchyValues: function(macroponentGR) {
      const {
          props,
          handledEvents,
          dispatchedEvents,
          rootComponentTag
      } = this.recurseThroughMCPExtends(macroponentGR);
      return {
          props,
          handledEvents: handledEvents.length > 0 ? handledEvents.join(',') : null,
          dispatchedEvents: dispatchedEvents.length > 0 ? dispatchedEvents.join(',') : null,
          rootComponentTag
      };
  },

  /**
   * @param macroponentGR {GlideRecord} the record we are getting values from
   * @param props {array} an array of property objects
   * @param handledEvents {array} an array of event sys_ids
   * @param dispatchedEvents {array} an array of event sys_ids
   * @param rootComponentTag {string} the component tag for the macroponent
   */
  recurseThroughMCPExtends: function(macroponentGR, props = [], handledEvents = [], dispatchedEvents = [], rootComponentTag = null) {
      const macroponentHandler = new Macroponent(["props", "handled_events", "dispatched_events", "extends", "root_component"]);
      const macroponentValues = macroponentHandler.getValuesFromGlideRecord(macroponentGR);
      if (!macroponentGR['extends'].nil()) {
          const parent = macroponentGR['extends'].getRefRecord();
          const parentValues = this.recurseThroughMCPExtends(parent, props, handledEvents, dispatchedEvents);
          return {
              props: props.concat(macroponentValues.props ?? [], parentValues.props),
              handledEvents: handledEvents.concat(macroponentValues?.handledEvents?.split(',') ?? [], parentValues.handledEvents),
              dispatchedEvents: dispatchedEvents.concat(macroponentValues?.dispatchedEvents?.split(',') ?? [], parentValues.dispatchedEvents),
              rootComponentTag: macroponentValues.rootComponentTag ? macroponentValues.rootComponentTag : rootComponentTag
          };
      }
      return {
          props: props.concat(macroponentValues.props ?? []),
          handledEvents: handledEvents.concat(macroponentValues?.handledEvents?.split(',') ?? []),
          dispatchedEvents: dispatchedEvents.concat(macroponentValues?.dispatchedEvents?.split(',') ?? []),
          rootComponentTag: macroponentValues.rootComponentTag ? macroponentValues.rootComponentTag : rootComponentTag
      };
  },

  /**
   * @param macroponentValueObjectArray {array} an array of macroponent definitions {type, sysId}
   */
  convertMacroponentDefinitions: function(macroponentValueObjectArray) {
      return macroponentValueObjectArray.reduce(function(acc, def) {
          acc[def.sysId] = def;
          return acc;
      }, {});
  },

  copy: function(macroponent, scope, domain, isTemplate) {
      let errorMessage = BuilderToolkitConstants.FAILED_TO_CREATE_MACROPONENT;
      const clientScriptHandler = new ClientScript();
      const addOnEventHandler = new UXAddOnEventMapping();
      const deleteFunctions = [];
      const macroponentId = typeof macroponent === 'string' ? macroponent : macroponent.getUniqueValue();
      const newMacroponentId = this.copyRecord(null, macroponentId, {
          associated_types: null
      }, scope, domain);
      const updatedMacroponent = this.getRecordById(newMacroponentId);
      deleteFunctions.push({
          handler: new Macroponent(),
          records: [{
              sysId: newMacroponentId
          }]
      });
      if (!newMacroponentId) {
          this.executeDeleteFunctions(deleteFunctions);
          return errorMessage;
      }
      // First we have to create our new client scripts
      const newClientScripts = clientScriptHandler.copyRecords(null, `macroponent=${macroponentId}`, {
          macroponent: newMacroponentId
      }, scope, domain);
      // If we created any we need to update our MCP with the new IDs, and prep to delete it all if something fails
      if (newClientScripts.length !== 0) {
          // Set up our deletion for them just in case
          deleteFunctions.push({
              handler: clientScriptHandler,
              records: newClientScripts
          });
          errorMessage = BuilderToolkitConstants.FAILED_TO_CREATE_CLIENT_SCRIPT;
          if (newClientScripts.some((result) => result === false)) {
              this.executeDeleteFunctions(deleteFunctions);
              return errorMessage;
          } else {
              const oldScripts = clientScriptHandler.getRecordsByQuery(`macroponent=${macroponentId}`);
              const newScripts = clientScriptHandler.getRecordsByQuery(`macroponent=${newMacroponentId}`);
              let composition = JSON.stringify(updatedMacroponent.composition);
              let data = JSON.stringify(updatedMacroponent.data);
              let internalEventMappings = JSON.stringify(updatedMacroponent.internalEventMappings);
              // Loop through all of the old clientScripts and find the matching ID and replace all places where usages could exist
              if (oldScripts) {
                  oldScripts.forEach((oldScript) => {
                      const matchingNewScript = newScripts.find((script) => script.name === oldScript.name);
                      composition = composition.replaceAll(oldScript.sysId, matchingNewScript.sysId);
                      data = data.replaceAll(oldScript.sysId, matchingNewScript.sysId);
                      internalEventMappings = internalEventMappings.replaceAll(oldScript.sysId, matchingNewScript.sysId);
                  });
              }
              updatedMacroponent.composition = JSON.parse(composition);
              updatedMacroponent.data = JSON.parse(data);
              updatedMacroponent.internalEventMappings = JSON.parse(internalEventMappings);

              // Update our MCP with the new clientScript info replaced
              this.updateRecord(updatedMacroponent);
          }
      }
      const newAddonEventHandlers = addOnEventHandler.copyRecords(null, `parent_macroponent=${macroponentId}`, {
          parent_macroponent: newMacroponentId
      }, scope, domain);
      if (newAddonEventHandlers.length !== 0) {
          deleteFunctions.push({
              handler: addOnEventHandler,
              records: newAddonEventHandlers
          });
          errorMessage = BuilderToolkitConstants.FAILED_TO_CREATE_ADDON_EVENT_MAPPING;
          if (newAddonEventHandlers.some((result) => result === false)) {
              this.executeDeleteFunctions(deleteFunctions);
              return errorMessage;
          }
      }
      return {
          newMacroponentId,
          newClientScripts,
          newAddonEventHandlers
      };
  },

  type: 'Macroponent'
});

Sys ID

9014f1f185761110f877e10cffeb7b80

Offical Documentation

Official Docs: