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)

New version of Angular timesheet project

There is a new version of this tutorial available:

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.

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;
    });
  }

}