Overview

  • Angular timesheet component that displays one day per row.
  • Calculates daily totals for each row.
  • Includes a trial version of DayPilot Pro for JavaScript (see License below)

License

Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript. Buy a license.

Generate a Timesheet using Online Builder

This project was generated by the Timesheet configurator from Daypilot UI Builder.

It generates an Angular application with the Angular Scheduler component configured to display a timesheet.

Timesheet Header Columns: Daily Totals

We will configure the timesheet component to display two columns in the row header:

  • Day
  • Total

This can be done using rowHeaderColumns property:

config: DayPilot.SchedulerConfig = {
  rowHeaderColumns: [
    { title: "Day" },
    { title: "Total"}
  ],
  // ...

};

The first column (Day) displays the default content (the date).

We will set the content of the second column (Total) using onBeforeRowHeaderRender event:

config: DayPilot.SchedulerConfig = {
  // ...
  onBeforeRowHeaderRender: function (args) {
    args.row.horizontalAlignment = "center";

    let duration = args.row.events.totalDuration();
    if (duration.totalSeconds() > 0) {
      let str = duration.toString("H:mm");
      if (duration.totalDays() >= 1) {
        str = Math.floor(duration.totalHours()) + ":" + duration.toString("mm");
      }

      args.row.columns[1].html = str + " hours";
    }
  },
  // ...
};

Full Source Code

import {Component, ViewChild, AfterViewInit} from "@angular/core";
import {DayPilot, DayPilotSchedulerComponent} from "daypilot-pro-angular";
import {DataService} from "./data.service";

@Component({
  selector: 'timesheet-component',
  template: `<daypilot-scheduler [config]="config" [events]="events" #timesheet></daypilot-scheduler>`,
  styles: [``]
})
export class TimesheetComponent implements AfterViewInit {

  @ViewChild("timesheet", {static: false})
  timesheet: DayPilotSchedulerComponent;

  events: any[] = [];

  config: DayPilot.SchedulerConfig = {
    rowHeaderColumns: [
      { title: "Day" },
      { title: "Total"}
    ],
    onBeforeRowHeaderRender: function (args) {
      args.row.horizontalAlignment = "center";

      let duration = args.row.events.totalDuration();
      if (duration.totalSeconds() > 0) {
        let str = duration.toString("H:mm");
        if (duration.totalDays() >= 1) {
          str = Math.floor(duration.totalHours()) + ":" + duration.toString("mm");
        }

        args.row.columns[1].html = str + " hours";
      }
    },
    timeHeaders: [{"groupBy":"Hour"},{"groupBy":"Cell","format":"mm"}],
    scale: "CellDuration",
    cellDuration: 30,
    days: DayPilot.Date.today().firstDayOfWeek().daysInMonth(),
    viewType: "Days",
    startDate: DayPilot.Date.today().firstDayOfMonth(),
    showNonBusiness: true,
    businessWeekends: false,
    allowEventOverlap: false,
    onTimeRangeSelected: function (args) {
      var dp = this;
      DayPilot.Modal.prompt("Create a new record:", "Record 1").then(function(modal) {
        dp.clearSelection();
        if (!modal.result) { return; }
        dp.events.add(new DayPilot.Event({
          start: args.start,
          end: args.end,
          id: DayPilot.guid(),
          resource: args.resource,
          text: modal.result
        }));
      });
    },
  };

  constructor(private ds: DataService) {
  }

  ngAfterViewInit(): void {
    var from = this.timesheet.control.visibleStart();
    var to = this.timesheet.control.visibleEnd();
    this.ds.getEvents(from, to).subscribe(result => {
      this.events = result;
    });
  }

}