Tutorials/Power Apps/Build a Custom Weekly Work Log App in Power Apps
Power Appsintermediate

Build a Custom Weekly Work Log App in Power Apps

Design a flexible time entry system with dynamic rows, inline editing, automatic totals, and SharePoint storage.

NA
Narmer Abader
@narmer · Published June 3, 2026

Tracking how people spend their time is a common business need, and Power Apps makes it surprisingly easy to build a tailored solution. Instead of using a generic template, creating your own app gives you full control over the fields, validation, and approval flow you may want later.

In this guide you'll walk through building a weekly work log where users can add multiple rows representing different activities, enter hours for each weekday, see a running total, and save everything back to SharePoint. The same principles apply if your week starts on Sunday or your team uses different categories – you'll learn the patterns that make the app adaptable.

The Scenario You'll Build For

Imagine a small consultancy where each consultant fills in a weekly summary of how they spent their time. Every week they can have several lines such as:

  • Client Meeting
  • Development Work
  • Internal Admin
  • Training
  • Other

Each line holds hours for Monday through Friday, and a calculated total. After editing, the user saves the entire week in one go. Managers (added later) can then review and approve entries.

This example uses a SharePoint list as the data source, but you can substitute Dataverse or Excel with minimal changes.

Creating the SharePoint List

First, set up a list named WeeklyTimeLog with these columns:

Column NameTypeNotes
ActivitySingle line of textDropdown values will come from the app
MonNumberWhole or decimal hours
TueNumber
WedNumber
ThuNumber
FriNumber
TotalCalculatedFormula: =Mon+Tue+Wed+Thu+Fri

The calculated column is useful for reporting outside Power Apps, but you'll also compute the total inside the app for rows that haven't been saved yet.

Starting the App in Power Apps Studio

  1. Open Power Apps Studio and create a new blank phone app.
  2. Go to the Data pane and add your WeeklyTimeLog list as a data source.
  3. Rename the screen to something like scrn_TimeLog.

Now we'll build the interface without relying on any built-in layout template – just containers, labels, and a gallery.

Building the Header and Action Bar

At the top of the screen, add a Label for the app title – for example "Week Log". Below it place a horizontal Container that will hold a + button and, later, a Save icon.

Inside that container, insert an Add icon (choose Icon.Add). Set its OnSelect to create a new blank row in a local collection:

powerfxOnSelect of the Add icon
Collect(colLogEntries, Defaults('WeeklyTimeLog'))

The collection colLogEntries will hold all rows currently being edited. It starts empty; the user adds rows as needed.

Column Headers

To make the input area easy to scan, add six Label controls inside a horizontal container placed just below the action bar. Use these texts:

Activity, Mon, Tue, Wed, Thu, Fri, Total

Name each label so you can reference its position later, for example:

  • lbl_ActivityHeader
  • lbl_MonHeader
  • lbl_TueHeader
  • lbl_WedHeader
  • lbl_ThuHeader
  • lbl_FriHeader
  • lbl_TotalHeader

Set the container's LayoutMode to Horizontal, adjust LayoutGap to 5 or 10, and give each label a fixed Width you'll reuse for the corresponding inputs. (In a real app you might calculate widths proportionally, but fixed widths work fine for a phone layout.)

Add a Vertical gallery and set its Items property to the collection:

powerfxGallery Items property
colLogEntries

Adjust the TemplateSize to around 80 and TemplatePadding to 0 so rows are compact.

Inside the gallery you'll place:

  1. A Dropdown for the Activity column.

    • Set Items to ["Client Meeting", "Development Work", "Internal Admin", "Training", "Other"].
    • Set Default to ThisItem.Activity so that existing values survive screen navigation.
  2. Five Text Inputs for Mon through Fri.

    • Name them txt_Mon, txt_Tue, txt_Wed, txt_Thu, txt_Fri.
    • Set their Default to the corresponding ThisItem.Mon, ThisItem.Tue, etc.
    • Change the input format to number: TextFormat = TextFormat.Number.
    • Align each input under its header by putting its X property equal to the header's X property. For example:
    powerfxX property of txt_Mon
    lbl_MonHeader.X

    Set the Width to the header's Width as well. Repeat for the other fields.

  3. A Label for the calculated total of each row.

    • Position it at lbl_TotalHeader.X and use the same Width.
    • Its Text property:
powerfxTotal label inside the gallery
Coalesce(
  Sum(
      Value(txt_Mon.Text),
      Value(txt_Tue.Text),
      Value(txt_Wed.Text),
      Value(txt_Thu.Text),
      Value(txt_Fri.Text)
  ),
  0
)

The Coalesce function prevents a blank from showing when all inputs are empty.

Deleting a Row

Insert a Trash icon (or use Icon.Delete) at the right side of the gallery template. Its OnSelect should both remove the item from the collection and, if the row has already been saved to SharePoint, queue it for deletion later.

powerfxOnSelect of the Delete icon
Remove(colLogEntries, ThisItem);
If(
  !IsBlank(ThisItem.ID),
  Collect(colDeleteLogEntries, ThisItem)
)

The separate delete collection is a safe pattern: the actual SharePoint deletion happens only when the user clicks the final Save button.

Saving Everything Back to SharePoint

Add a Save icon (or a button) in the action bar. When clicked, the app should:

  • Update any rows that already have an ID (existing records).
  • Create new rows for those without an ID.
  • Delete rows collected in colDeleteLogEntries.

The cleanest approach is to iterate over the gallery's AllItems using ForAll. Because ForAll calls Patch for each row, it can handle millions of records – though for a typical weekly log (under 50 rows) you won't hit any delegation limits.

powerfxOnSelect of the Save icon
// Update or create each row
ForAll(
  gal_LogEntries.AllItems,
  Patch(
      'WeeklyTimeLog',
      If(IsBlank(ID), Defaults('WeeklyTimeLog'), LookUp('WeeklyTimeLog', ID = ID)),
      {
          Activity: drp_Activity.Selected.Value,
          Mon: Value(txt_Mon.Text),
          Tue: Value(txt_Tue.Text),
          Wed: Value(txt_Wed.Text),
          Thu: Value(txt_Thu.Text),
          Fri: Value(txt_Fri.Text)
      }
  )
);
// Remove rows the user marked for deletion
ForAll(
  colDeleteLogEntries,
  Remove('WeeklyTimeLog', ThisRecord)
);
// Clear the temporary collections
Clear(colDeleteLogEntries);
ClearCollect(colLogEntries, 'WeeklyTimeLog')   // optional: reload clean data

After saving, you may reload the SharePoint list into the collection so that the gallery shows the current saved state.

Loading Existing Data When the App Starts

To show past entries when the user opens the app, load the SharePoint list into the collection on screen OnVisible:

powerfxScreen OnVisible
ClearCollect(colLogEntries, 'WeeklyTimeLog')

This automatically populates the gallery with previously saved rows. The user can then add new rows, edit existing ones, or delete them before saving again.

Performance and Delegation Notes

Because all data manipulation happens inside a local collection (colLogEntries), delegation is not an issue for the add/edit/delete operations. The only delegation-sensitive step is the initial ClearCollect from SharePoint. For a list with fewer than 2,000 items this is fine. If you expect many users with many weeks of data, consider adding a filter (e.g., Filter('WeeklyTimeLog', WeekOf = selectedWeek)) before loading into the collection.

The calculated Total column in SharePoint is a convenience for reporting – the app computes its own total per row, so there is no dependency on SharePoint recalculation delays.

Common Pitfalls and How to Avoid Them

  • Text inputs not showing saved values – Make sure the Default property points to ThisItem.ColumnName and that the column exists in the collection. After ClearCollect, columns match SharePoint exactly.
  • Dropdown loses selection after save – Because Patch returns a new record, the gallery may refresh. Use ThisItem.Activity in the Default property rather than a static default.
  • Gallery rows don't align with headers – Ensure both the header container and the gallery template use the same X offsets and Width values. Setting LayoutGap in the gallery to 0 and manually positioning controls is more reliable.
  • Total label shows blank – The Coalesce function returns the sum only if at least one input contains a number. If all inputs are empty, Sum(...) results in blank, and Coalesce returns 0. That's correct behavior.
  • Delete collection not cleared – Always Clear(colDeleteLogEntries) after processing deletions, otherwise duplicates can occur.

Final Recommendation

The design shown here gives you a solid foundation for any kind of time tracking, job logging, or even simple expense entry. Start with the SharePoint list and a gallery-driven UI; later you can add a header view (week selection, approval status) and integrate a review screen for managers.

Building it yourself means you understand every piece and can adapt it when your business rules change. That's far more valuable than downloading a template.

References