User Context Display Widget Pattern
Overview
A widget that displays information about the currently logged-in user, sourced entirely from pageContext.userData. No API calls required — the platform injects the user's profile instance data directly into pageContext.
When to Use
- Show a user profile card on a Home layout or a View layout tab
- Display logged-in user details (name, designation, contact) as part of a personalized dashboard
- Show user-specific information that doesn't require a separate API fetch
Applicable Layout Types
| Target | Notes |
|---|---|
HomePage | Profile card on home page |
ViewLayout | User info panel on an instance view tab |
Any | Can be placed anywhere |
userData Shape
pageContext.userData = {
userId: string,
name: string, // Display name (e.g. "John Doe")
email: string,
roles: string[], // Role names assigned to the user
isAdmin: boolean,
typeInstanceId: string, // ID of the UserProfile instance
pictureUrl: string, // URL of user's avatar image
profile: { // Full UserProfile instance object
id: string,
name: string,
instanceTypeName: string, // 'UserProfile'
attributes: AttributeObject[], // UserProfile attribute values
state: object,
lifecycle: object,
},
}
Pattern Structure
- Destructure
userDatafrompageContext - Access
userData.profile.attributesand find each attribute by name - Use
Enums.AttributeTypesfor type-safe value extraction, or access the typed value field directly - Render a display-only card — no
onAttributeEdit, no API calls
Code Example
function UserProfileDetailsWidget(pageContext) {
const { protrakUtils, protrakComponents } =
React.useContext(customWidgetContext);
const { Enums } = protrakUtils;
const { Text, Box, H2, H4, Label } = protrakComponents;
const { userData } = pageContext;
// Guard: profile may not be loaded yet
if (!userData || !userData.profile) {
return null;
}
const profileAttrs = userData.profile.attributes || [];
// Helper: find an attribute by name and extract its display value
const getAttrValue = (attrName) => {
const attr = profileAttrs.find((a) => a.name === attrName);
if (!attr) return '-';
switch (attr.type) {
case Enums.AttributeTypes.Text:
return attr.textValue || '-';
case Enums.AttributeTypes.Numeric:
case Enums.AttributeTypes.Currency:
return attr.numericValue ?? '-';
case Enums.AttributeTypes.Boolean:
return attr.booleanValue ? 'Yes' : 'No';
case Enums.AttributeTypes.Date:
case Enums.AttributeTypes.DateTime:
return attr.dateValue || '-';
case Enums.AttributeTypes.Picklist:
return (attr.arrayValue || []).join(', ') || '-';
case Enums.AttributeTypes.Reference:
return (
(attr.referenceValues || []).map((r) => r.name).join(', ') || '-'
);
default:
return '-';
}
};
const firstName = getAttrValue('STANDARDFirstName');
const lastName = getAttrValue('STANDARDLastName');
const contact = getAttrValue('STANDARDPhone');
const designation = getAttrValue('STANDARDDesignation');
return (
<Box style={{ display: 'flex', flexDirection: 'column', margin: '1rem' }}>
<H2>{userData.name}</H2>
<div style={{ marginTop: '0.5rem' }}>
<Text>
<b>First Name:</b> {firstName}
</Text>
<Text>
<b>Last Name:</b> {lastName}
</Text>
<Text>
<b>Contact:</b> {contact}
</Text>
<Text>
<b>Designation:</b> {designation}
</Text>
</div>
</Box>
);
}
Accessing All userData Properties
const { userData } = pageContext;
// Basic user info (always available)
userData.name; // "John Doe"
userData.email; // "john@company.com"
userData.roles; // ["Admin", "Project Manager"]
userData.isAdmin; // true/false
userData.pictureUrl; // avatar URL
// UserProfile instance attributes (requires profile to be loaded)
const profileAttrs = userData.profile?.attributes || [];
const phone = profileAttrs.find((a) => a.name === 'STANDARDPhone')?.textValue;
Checking User Roles
A common pattern for role-based rendering inside any widget:
const { userData } = pageContext;
const roles = userData?.roles || [];
const isAdmin = roles.includes('Admin');
const isManager = roles.includes('Project Manager');
const canViewSensitiveData = ['Admin', 'Finance', 'Management'].some((r) =>
roles.includes(r)
);
if (!canViewSensitiveData) {
return <span>Access Restricted</span>;
}
Real Examples
UserProfileDetailsWidget.js— Construction360, MountMeru