Wu's Demo · Industry Solutions

Build apps that transform your industry.

From hospital floors to legal chambers to capital project pipelines — Wu's Demo + Power Fx delivers enterprise-grade solutions without enterprise-grade complexity.

🏥
Healthcare
Healthcare informatics, clinical process improvement, initiative tracking and operational outcomes.
⚖️
Legal
Case management, contract tracking, billing automation and hearing calendars.
📋
Projects
Project tracking, task assignment, sprint progress and team workload management.
🏥
Healthcare
Informatics & Process PMO
Projects
📋 Active Initiatives
🔄 Process Workflows
📊 Outcomes Tracking
📁 Documentation
🔔 Milestones
Administration
👥 Project Teams
🏢 Departments
⚙️ Settings
System
4 Active Sessions
Informatics Project Dashboard
XXX Health System · Clinical & Operational Improvement
Filter(Initiatives, Department = varSelectedDept && Status = "In Progress" && DateDiff(TargetDate, Today(), Days) < 90 )
Active Initiatives
24
↑ 4 added this quarter
On Schedule
18
75% completion rate
At Risk
4
Requires escalation
Avg Cycle Time
38d
↓ 11% vs last quarter
Active Initiatives
On Track At Risk In Review
InitiativeDomainStatusTarget DatePriority
GS
Appointment Follow-Up Process
Clinical Ops On Track Apr 30, 2026 High
GT
Discharge Process Redesign
Care Transitions At Risk Mar 28, 2026 Critical
GN
Referral Tracking Automation
Informatics On Track May 15, 2026 Standard
GR
Compliance Reporting Dashboard
Quality & Safety In Review Apr 10, 2026 High
New Initiative Intake
INTAKE
Initiative Name
Domain
Lead Department
Priority
Objective / Problem Statement
// Log new initiative to SharePoint Patch(Initiatives, Defaults(Initiatives), { Title: txtInitiative.Text, Domain: drpDomain.Selected.Value, SubmittedBy: User().FullName, SubmittedOn: Now(), Status: "Pending Review" } )
// Toggle at-risk filter view Set(varAtRiskOnly, !varAtRiskOnly); UpdateContext({locShowBanner: true})
💡 Power Fx tip: Use Set() for global app state and UpdateContext() for screen-local variables like modal toggles and filter flags.
LIVE Refreshed 4 min ago
Initiative Status Breakdown
All active projects · Q2 2026
On Track (18) At Risk (4) Delayed (2)
Initiatives Opened vs Closed
Last 6 months · XXX Health System
Initiatives by Domain
Current quarter
📋
ProjectTrack
Project Management
Navigation
📋 All Projects
✅ My Tasks
📅 Timeline
📊 Reports
🔔 Notifications
Management
👥 Team
🗂️ Resources
⚙️ Settings
Status
3 Active Sprints
Project Dashboard
Q1 2026 · Active Portfolio Overview
// Filter active projects assigned to current user SortByColumns( Filter(Projects, Status <> "Closed" && DateDiff(Today(), DueDate, Days) <= 30 ), "DueDate", SortOrder.Ascending )
Active Projects
18
Across 4 departments
On Track
13
72% of portfolio
At Risk
4
Needs attention
Overdue Tasks
7
Across all projects
Active Projects
On Track ⚠️ At Risk Delayed
ProjectOwnerPriorityDue DateStatus
Portal Redesign
GS
GuwenJ Smith
High Mar 20 ⚠️ At Risk
Data Migration
GT
GuwenJ Torres
Medium Apr 05 On Track
Security Audit
GN
GuwenJ Nguyen
High Mar 31 On Track
Onboarding App
GR
GuwenJ Rivera
Low May 15 Delayed
Sprint Progress
Q1 SPRINT 3
Portal Redesign38%
Data Migration74%
Security Audit61%
Onboarding App22%
New Task
ASSIGN
Task Title
Project
Priority
Assigned To
Due Date
// Save task and notify assignee Patch(Tasks, Defaults(Tasks), { Title: txtTask.Text, Project: drpProject.Selected.Value, AssignedTo: txtAssignee.Text, DueDate: dateDue.SelectedDate, CreatedBy: User().Email, Status: "Open" } ); Notify("Task created", NotificationType.Success)
// Power Fx Formula Reference · Scalability Edition
Delegable Functions & Scalability Guide
A practitioner's reference for building Power Apps that scale. Every formula is tagged for delegation support — the single most critical factor when connecting to SharePoint, Dataverse, or SQL at enterprise volume.
✅ Fully Delegable
Query runs on the server. Scales to millions of rows. Recommended for production apps.
⚠️ Partially Delegable
Some conditions delegate; others don't. Wrap with delegable outer filter. Test at scale.
❌ Non-Delegable
Pulls up to 2,000 rows then filters locally. Use only on small datasets or collections.
GuwenJ · RECOMMENDATION
Top 5 Rules for Scalable Power Apps
1️⃣
Always use Filter() over Search() on large sources
Filter() with equality/comparison operators delegates to SharePoint & Dataverse. Search() does NOT delegate — it's limited to 2,000 rows.
2️⃣
Prefer Dataverse over SharePoint for complex queries
Dataverse supports full delegation for Filter(), SortByColumns(), CountRows(), and Sum(). SharePoint is limited on multi-column sorts.
3️⃣
Use ClearCollect() at OnStart for non-delegable needs
Load small reference tables (config, lookups, roles) into collections once on startup. Then Filter(colRef, ...) locally — fast and safe.
4️⃣
Never put Sum/Average directly on a SharePoint list
Sum(SharePointList, Column) is non-delegable. Instead: Sum(ClearCollect snapshot, Column) or move aggregations to a Dataverse calculated column.
5️⃣
Turn on delegation warnings — treat them as errors
In Power Apps Studio → Settings → Upcoming Features → enable delegation warnings. Every yellow triangle is a potential data loss bug at scale. Resolve all warnings before deploying to production.
📂 Data Operations
🔍
Filter()
Query rows from a data source
✅ Fully Delegable
Filter(Patients, Department = drpDept.Selected.Value && Status = "Active" )
Returns matching rows in real-time. Combine conditions with && (AND) or || (OR). Works with SharePoint, Dataverse, SQL, and collections.
💡 Scalability note: Delegates to SharePoint, Dataverse & SQL. Use equality, comparison, and simple boolean operators. Avoid using functions like Lower() inside Filter — they break delegation.
✏️
Patch()
Create or update a record
✅ Fully Delegable
// Update existing record Patch(Cases, ThisItem, {Status: "Closed", ClosedBy: User().Email} ) // Create new record Patch(Cases, Defaults(Cases), {Title: txtTitle.Text} )
Use Defaults() to create a new record, or pass ThisItem to update the current row. Works on any connected data source.
💡 Scalability note: Patch() always runs server-side. Safe to use on any data source at any scale. Batch multiple Patch() calls into one using a table argument for efficiency.
🗑️
Remove()
Delete a record
⚠️ Partially Delegable
// Delete single record Remove(ProjectTasks, ThisItem) // Confirm before deleting If(locConfirmed, Remove(ProjectTasks, ThisItem); Notify("Record deleted") )
Always pair with a confirmation variable or dialog to prevent accidental deletes. Use RemoveIf() to delete multiple rows matching a condition.
💡 Scalability note: Remove(table, record) is delegable. RemoveIf(table, condition) delegates only if the condition itself is delegable — verify per data source.
🔗
LookUp()
Find a single matching record
✅ Fully Delegable
// Get field from related table LookUp(Employees, ID = varManagerID ).FullName // Pull a config value LookUp(Settings, Key = "MaxItems" ).Value
Returns the first matching row. Ideal for resolving foreign keys and pulling config values. Combine with & to build dynamic labels.
💡 Scalability note: LookUp() delegates when the filter predicate is delegable. Faster than Filter()[0] — returns exactly one record without pulling the full dataset.
📋
Collect() / ClearCollect()
In-memory collections
❌ Non-Delegable
// Append a task to local list Collect(colMilestones, {Phase: txtPhase.Text, Owner: User().Email} ) // Reset and rebuild from source ClearCollect(colMilestones, Filter(Projects, Status = "Active") )
Collect() appends; ClearCollect() resets first. Use for offline caching, shopping carts, and multi-select lists.
💡 Scalability note: Collections live in memory — all operations on them are local. Best practice: load with ClearCollect() at OnStart from a delegable Filter(), then work locally on the collection.
📊
SortByColumns()
Sort a table dynamically
⚠️ Partially Delegable
SortByColumns( Filter(Cases, Status="Open"), "Deadline", SortOrder.Ascending, "Priority", SortOrder.Descending )
Chains with Filter() seamlessly. Supports multiple sort columns and dynamic sort direction via a toggle variable.
💡 Scalability note: Delegates on Dataverse (multi-column). SharePoint only delegates single-column sort on indexed columns. Always test with the delegation warning enabled.
⚡ Logic & Control Flow
🔀
If() / Switch()
Conditional branching
❌ Non-Delegable
// Multi-branch If If(Score >= 90, "High", Score >= 60, "Medium", "Low") // Switch on a value Switch(Status, "Open", "Active", "Closed", "Inactive", "Pending")
If() supports chained conditions without nesting. Switch() is cleaner when matching one value against many cases.
💡 Scalability note: If() and Switch() are local logic — never used inside Filter() on a data source. Use them on the result of a delegable Filter(), not as its condition.
🛡️
IsBlank() / IsEmpty()
Null & empty checks
⚠️ Partially Delegable
// Validate required field If(IsBlank(txtEmail.Text), Notify("Email required", NotificationType.Error) ) // Check if collection is empty If(IsEmpty(colSelectedItems), Notify("Cart is empty") )
Use IsBlank() for text/field validation and IsEmpty() for tables and collections. Essential for form validation before Patch().
💡 Scalability note: IsBlank() delegates for simple column checks in Dataverse. Does not delegate in SharePoint nested inside complex conditions. Use for form validation (always local).
Set() / UpdateContext()
Global & local variables
✅ Fully Delegable
// Global — available everywhere Set(gblIsAdmin, User().Email = "[email protected]" ) // Local — this screen only UpdateContext({ locShowPanel: true, locSelectedID: ThisItem.ID })
Prefix globals with gbl and locals with loc. Set multiple local vars in one UpdateContext() call to reduce formula length.
💡 Scalability note: Variables are local state — no data source involved. Referencing a variable inside Filter() IS delegable as long as the variable contains a simple scalar value.
🚀
Navigate() + Back()
Screen navigation
✅ Fully Delegable
// Navigate and pass context Navigate(DetailScreen, ScreenTransition.Fade, {locRecord: ThisItem} ) // Return to previous screen Back(ScreenTransition.UnCover)
Pass context variables directly into the target screen via the third parameter — no globals needed for simple drill-down record patterns.
💡 Scalability note: Navigate() is a UI action — no data source involved. Pass context via the second parameter to avoid re-querying data on the target screen.
🔔
Notify()
In-app toast messages
Notify("Saved!", NotificationType.Success) Notify("Check fields", NotificationType.Warning, 3000) Notify("Save failed", NotificationType.Error)
Four types: Success, Warning, Error, Information. Optional third param sets display duration in milliseconds.
🚦
And() / Or() / Not()
Boolean operators
⚠️ Partially Delegable
// Button enabled only if valid !IsBlank(txtName.Text) && !IsBlank(txtEmail.Text) && gblIsAdmin // Show if either condition met IsNew || gblIsAdmin
Control button visibility, field editability, and screen access. The ! shorthand for Not() keeps formulas concise.
💡 Scalability note: AND (&&) / OR (||) between delegable conditions are delegable. Mixing a non-delegable condition (e.g., Search()) with && breaks delegation for the whole expression.
📅 Date & Time
📅
Today() / Now()
Current date and datetime
✅ Fully Delegable
Today() // 3/11/2026 Now() // 3/11/2026 14:32 // Custom formatted string Text(Now(), "mmm dd, yyyy") // "Mar 11, 2026" Text(Now(), "hh:mm AM/PM") // "02:32 PM"
Use Today() for date comparisons and Now() for timestamps. Wrap in Text() for any display format.
💡 Scalability note: Today() and Now() delegate in Filter() on Dataverse and SharePoint. Use DateAdd(Today(), -30, Days) inside Filter() to pull rolling windows of data.
⏱️
DateDiff()
Time between two dates
⚠️ Partially Delegable
// Days until deadline DateDiff(Today(), Deadline, Days) // Patient age in years DateDiff(DOB, Today(), Years) // Color overdue rows red If(DateDiff(DueDate,Today(),Days)>0, RGBA(255,0,0,0.1), Transparent)
Units: Days, Months, Years, Hours, Minutes. Negative result means the first date is after the second.
💡 Scalability note: DateDiff() does NOT delegate inside Filter(). Pre-calculate the target date with DateAdd() and compare against a column directly — that is delegable.
📆
DateAdd()
Add or subtract from a date
✅ Fully Delegable
// Expiry = today + 30 days DateAdd(Today(), 30, Days) // Next review in 6 months DateAdd(ReviewDate, 6, Months) // Default due date on new form DateAdd(Today(), 14, Days)
Calculate future/past dates for SLAs, expiry dates, and default form values. Use negative numbers to subtract.
💡 Scalability note: DateAdd() delegates when used as a scalar value in a Filter() comparison. Example: Filter(Tasks, DueDate < DateAdd(Today(), 7, Days)) is fully delegable.
🔤 Text & Numbers
🔤
Concatenate() / &
Combine strings
❌ Non-Delegable
// Full name txtFirst.Text & " " & txtLast.Text // Dynamic label "Case #" & Text(ThisItem.ID) & " · " & ThisItem.Status // Normalize input Upper(Trim(txtSearch.Text))
The & operator joins strings instantly. Use Upper(), Lower(), Trim() to normalize user input before saving.
💡 Scalability note: String operations (Concatenate, Upper, Lower, Trim) never delegate — they run locally. Never use them inside Filter() on a large data source.
🔎
Search() / StartsWith()
Live text search
❌ Non-Delegable (Search) / ⚠️ Partial (StartsWith)
// Search across multiple columns Search(Patients, txtSearch.Text, "Name", "Department" ) // Prefix-only match Filter(Milestones, StartsWith(Code, txtFilter.Text) )
Search() is case-insensitive and spans multiple columns. StartsWith() is faster for prefix-only matching against large datasets.
💡 Scalability note: Search() is non-delegable — limited to 2,000 rows. StartsWith() delegates on Dataverse & SharePoint for text columns. For scalable search, use StartsWith() inside Filter() instead.
🔢
Sum() / Average() / CountRows()
Aggregate functions
❌ Non-Delegable on SharePoint
// Total qty in cart Sum(colBudgetLines, EstimatedCost) // Average risk score Average(Patients, RiskScore) // Count open cases CountRows( Filter(Cases, Status="Open") )
Power KPI cards and dashboards. CountIf(table, condition) combines count + filter in one call for even cleaner formulas.
💡 Scalability note: Sum/Average/CountRows do NOT delegate on SharePoint — they pull all rows locally first. On Dataverse they delegate. Recommendation: move aggregates to Dataverse or use Power Automate flows to pre-compute totals.
👤 User & Context
👤
User()
Signed-in user properties
✅ Fully Delegable
User().FullName // "Jane Doe" User().Email // "[email protected]" User().Image // profile photo // Auto-stamp on submit Patch(Requests, Defaults(Requests), {SubmittedBy: User().Email, SubmittedOn: Now()} )
Auto-populate audit fields without any user input. User().Image can fill avatar Image controls directly — no extra steps.
💡 Scalability note: User() returns a local object — no server call. Cache User().Email in a variable at OnStart rather than calling User() repeatedly in Filter() conditions.
🔐
Role-Based Access
Show/hide UI by user role
✅ Fully Delegable
// Set once on app load Set(gblIsAdmin, User().Email = "[email protected]" ) // Button Visible property gblIsAdmin // Or check a Roles table !IsEmpty(Filter(Roles, Email = User().Email))
Set role flags in App.OnStart to avoid repeated lookups. Use the variable in Visible, DisplayMode, and Disabled properties across all screens.
💡 Scalability note: Setting role flags at OnStart via a delegable Filter() on a Roles table is the recommended pattern. Avoid repeated LookUp() calls per screen — set once, use everywhere.
🌐
Param()
Read URL launch parameters
✅ Fully Delegable
// Read ID from launch URL Param("CaseID") // Auto-filter on load Set(varDeepLink, If(IsBlank(Param("id")), "", Param("id") ) )
Enables deep linking — launch the app from Teams, email, or another system and pass record IDs to pre-filter or pre-populate screens automatically.
💡 Scalability note: Param() is a local function. Use it at OnStart to set variables, then pass those variables into delegable Filter() calls — enables deep-linked, pre-filtered app loads.