powerapps-common
Version:
Common Dataverse JavaScript Functions
344 lines (343 loc) • 10.4 kB
JavaScript
import { generateReport } from './models/report';
/**
* Set a field's requirement level
* @param fieldName Name of field
* @param requiredLevel Requirement level
* @param form Form context
*/
export function setFieldRequirementLevel(fieldName, requiredLevel, form) {
const field = form.getAttribute(fieldName.toLowerCase());
if (field == null) {
return false;
}
field.setRequiredLevel(requiredLevel);
return true;
}
/**
* Set a control's visibility
* @param controlName Name of control
* @param visible Visible
* @param allControls Apply to all controls
* @param form Form context
*/
export function setControlVisibility(controlName, allControls, visible, form) {
const control = form.getControl(controlName.toLowerCase());
if (control == null) {
return false;
}
if (allControls) {
control.getAttribute().controls.forEach((c) => {
c.setVisible(visible);
});
}
else {
control.setVisible(visible);
}
return true;
}
/**
* Set a control's label
* @param controlName Name of control
* @param label Label for control
* @param form Form context
*/
export function setControlLabel(controlName, label, form) {
const control = form.getControl(controlName.toLowerCase());
if (control == null) {
return false;
}
control.setLabel(label);
return true;
}
/**
* Set a default value on a field
* @param fieldName Name of field
* @param value Default value
* @param form Form context
* @param fireOnChange Fire field on change event
*/
export function setDefaultValue(fieldName, value, form, fireOnChange) {
const field = form.getAttribute(fieldName.toLowerCase());
if (field == null || field.getValue() != null) {
return false;
}
field.setValue(value);
if (fireOnChange == true) {
field.fireOnChange();
}
return true;
}
/**
* Add a form notification that is cleared after a certain time
* @param message Notification message
* @param level Form notification level
* @param uniqueId Unique Id for the message
* @param timeout Timeout before clearing the notififcation
* @param form Form context
*/
export function addFormNotification(message, level, uniqueId, timeout = 10000, form) {
form.ui.setFormNotification(message, level, uniqueId);
setTimeout(() => {
form.ui.clearFormNotification(uniqueId);
}, timeout);
return true;
}
/**
* Add an on change event to a field
* @param fieldName Name of field
* @param event Event to fire
* @param form Form context
*/
export function addOnChange(fieldName, event, form) {
const field = form.getAttribute(fieldName.toLowerCase());
if (field === null || field === undefined) {
return false;
}
// Prevent on change event from being added twice
field.removeOnChange(event);
field.addOnChange(event);
return true;
}
/**
* Remove an on change event from a field
* @param fieldName Name of field
* @param event Event to fire
* @param form Form context
*/
export function removeOnChange(fieldName, event, form) {
const field = form.getAttribute(fieldName.toLowerCase());
if (field === null || field === undefined) {
return false;
}
field.removeOnChange(event);
return true;
}
/**
* Set a value on a field
* @param fieldName Name of field
* @param value Value
* @param form Form context
* @param fireOnChange Fire field on change event
*/
export function setValue(fieldName, value, form, fireOnChange) {
const field = form.getAttribute(fieldName.toLowerCase());
if (field == null) {
return false;
}
// Only set value if it's changed
if (field.getValue() != value) {
field.setValue(value);
if (fireOnChange == true) {
field.fireOnChange();
}
}
return true;
}
/**
* Check if a field contains data
* @param fieldName Name of field
* @param form Form context
*/
export function fieldContainsData(fieldName, form) {
const field = form.getAttribute(fieldName.toLowerCase());
return field != null && field.getValue() != null;
}
/**
* Disable/enable controls for a field
* @param fieldName Name of control
* @param disabled Disable or enable field
* @param form Form context
*/
export function setDisabled(fieldName, allControls, disabled, form) {
const control = form.getControl(fieldName.toLowerCase());
if (control == null) {
return false;
}
if (allControls) {
control.getAttribute().controls.forEach((c) => {
c.setDisabled(disabled);
});
}
else {
control.setDisabled(disabled);
}
return true;
}
/**
* Add presearch event to lookup control
* @param fieldName Name of control
* @param handler Handler for presearch
* @param form Form context
*/
export function addPreSearch(fieldName, handler, form) {
const field = form.getAttribute(fieldName.toLowerCase());
if (field == null) {
return false;
}
field.controls.forEach((c) => {
c.addPreSearch(handler);
});
return true;
}
/**
* Navigate to different form
* @param form Form context
* @param label Label of form to navigate to
*/
export function navigateToForm(form, label) {
const current = form.ui.formSelector.getCurrentItem();
if (current.getLabel() !== label) {
form.ui.formSelector.items.forEach((f) => {
if (f.getLabel() === label) {
f.navigate();
}
});
}
}
/**
* Filter lookup field
* @param form Form context
* @param lookupAttribute Logical name of attribute to which the filter will apply
* @param attributeFilter Logical name of the attribute to filter on
* @param values Values for the filter
*/
export function addLookupFilter(form, lookupAttribute, attributeFilter, values) {
if (values.length === 0) {
return false;
}
const value = values.map((v) => `<value>${v}</value>`);
const filter = ['<filter>', `<condition attribute='${attributeFilter}' operator='in'>`, value, '</condition>', '</filter>'].join('');
form.getAttribute(lookupAttribute)?.controls.forEach((c) => c.addCustomFilter(filter));
return true;
}
/**
* Add on save event
* @param form Form context
* @param event Event
*/
export function addOnSave(form, event) {
// Prevent event from being added twice
form.data.entity.removeOnSave(event);
form.data.entity.addOnSave(event);
}
/**
* Get formatted value from entity
* @param entity Entity
* @param field Field
*/
export function getFormattedValue(entity, field) {
return entity[`${field}@OData.Community.Display.V1.FormattedValue`];
}
/**
* Parse GUID by removing curly braces and converting to uppercase
* @param id GUID to parse
*/
export function parseGuid(id) {
if (id === null || id === 'undefined' || id === '') {
return '';
}
id = id.replace(/[{}]/g, '');
if (/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(id)) {
return id.toUpperCase();
}
else {
throw Error(`Id ${id} is not a valid GUID`);
}
}
/**
* Check if two GUIDs are equal
* @param id1 GUID 1
* @param id2 GUID 2
*/
export function areGuidsEqual(id1, id2) {
try {
id1 = parseGuid(id1);
id2 = parseGuid(id2);
if (id1 === null || id2 === null || id1 === undefined || id2 === undefined || id1 === '' || id2 === '') {
return false;
}
return id1.toLowerCase() === id2.toLowerCase();
}
catch (ex) {
return false;
}
}
/**
* Generate a pre-filtered report
* @param rowId Row id of record
* @param reportId Report id
* @param table Logical table name of record
* @param format Format for exported report
* @param reportParameter Report pre filter parameter name
*/
export async function generatePrefilteredReport(rowId, reportId, table, format, parameterName) {
const config = {
id: rowId,
table: table,
reportId: reportId,
format: format,
parameterName: parameterName
};
const report = await generateReport(config);
return report;
}
/**
* Get environment variable
* @param variableName Name of environment variable to return
* @returns Current or default variable value
*/
export async function getEnvironmentVariable(variableName) {
const fetch = [
'?fetchXml=',
'<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">',
'<entity name="environmentvariabledefinition">',
'<attribute name="defaultvalue" alias="default" />',
'<filter type="and">',
`<condition attribute="schemaname" operator="eq" value="${variableName}" />`,
'</filter>',
'<link-entity name="environmentvariablevalue" from="environmentvariabledefinitionid" to="environmentvariabledefinitionid" link-type="outer">',
'<attribute name="value" alias="current" />',
'</link-entity>',
'</entity>',
'</fetch>'
].join('');
const variables = await Xrm.WebApi.retrieveMultipleRecords('environmentvariabledefinition', fetch);
if (variables.entities.length === 0) {
return;
}
const variable = variables.entities[0];
return variable.current ?? variable.default;
}
/**
* Pause execution for specified period of time
* @param ms Time to pause in milliseconds
* @returns Promise
*/
export async function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Set a fields value based on the name of a lookup field
* @param fieldToSet Logical name of field to set
* @param lookupField Logical name of lookup field
* @param form Form context
* @returns True or false if value was set
*/
export function setValueFromLookupFieldName(fieldToSet, lookupField, form) {
const lookup = form.getAttribute(lookupField)?.getValue();
if (lookup == null) {
return false;
}
form.getAttribute(fieldToSet)?.setValue(lookup[0].name ?? '');
return true;
}
/**
* Check if a user has a role
* @param role Name or id of role
*
*/
export function userHasRole(role) {
const userRoles = Xrm.Utility.getGlobalContext().userSettings.roles.get();
const matchingRole = userRoles.find((item) => item.name?.toLowerCase() === role.toLowerCase() || areGuidsEqual(item.id, role));
return matchingRole != undefined;
}