Stacked Calendar

The stacked calendar is a component specifically written for time and attendance reporting. It is a complex component with a rich interface that can be controlled generically, however the component makes some assumptions based on it being a time reporting component, so using it generically might or might not not give good results. Details on what is assumed for each property is specified on that property description.

The stacked calendar is comprised of a week selector and individual stacks for each day. The stacks contains events of two types, reports and attendances, where attendances are a more generic type than reports and can be displayed in various ways. Typically for events in the stacked calendar is that they have duration but not start and end times. So the stacked calendar is useful when wanting to sum up the total time spent over several events for a specific day.

The parts of the stacked calendar


The stacked calendar uses a main entityset and three arrays on that entityset. Each of these four parts has its own part in the stacked calendar marble syntax, there is also a fifth part which typically uses the attendance array, although it could use any other or even its own array.

main

The main entityset would typically be a person of some kind, the properties on the stacked calendar for this part has to do with global values such as week length and which day starts the week and how many minutes each step in the drag and drop should add or remove.

daysinfo

The daysinfo array contains day specific properties keyed on the date property. It controls things like the schedule duration for the day, and connections to attributes with the server calculated values for how much is left to report for a day (the stacked calendar does not do any calculations on the client, except really basic layout ones).

reports

The reports array contains your basic events for the stacked calendar. These will be displayed in the normal stack of the day they belong to.

attendance

The attendance array contains your generic events for the stacked calendar, these events are expected to have a type which controls where to display the events, available places are in the normal stack together with reports, in the small stack to the right of the normal stack and as a list together with daysinfo specific things.

progressarea

The progress area is supposed to show a summary of the events for the complete week.

Stacked Calendar Areas

Marble


Entities and Projection

The basic data structure for the stacked calendar would look something like this example, this is the data structure used in the examples below:

Person.entity

Id                  TEXT(6)/UPPERCASE
PersonName          TEXT(200)
StartOfWeek         NUMBER(1)
WeekLength          NUMBER(1)
MinutesIncrements   NUMBER(3)

DayInfo.entity

ForDay              DATE
PersonId            TEXT(6)/UPPERCASE
ScheduleDuration    NUMBER(4)
RemainingJob        NUMBER(4)
RemainingWage       NUMBER(4)
Status              TEXT(200)
Note                TEXT(2000)

Report.entity

ForDay              DATE
PersonId            TEXT(6)/UPPERCASE
JobMinutes          NUMBER(4)
Project             TEXT(10)/UPPERCASE
SubProject          TEXT(10)/UPPERCASE
Activity            TEXT(10)/UPPERCASE
Description         TEXT(2000)

Attendance.entity

ForDay              DATE
PersonId            TEXT(6)/UPPERCASE
WageMinutes         NUMBER(4)
WageType            ENUMERATION(WageType)
Description         TEXT(2000)

WageType.enumeration

Overtime
ExtraTime
Increment
Absence
BalanceAccural
BalanceWithdrawal
Information
Normal

StackedCalendar.projection

----------------------------- MAIN ENTRY POINTS -----------------------------
entityset Persons for Person;
entityset DayInfos for DayInfo;
entityset AttendanceItems for AttendanceItem;
entityset ReportItems for ReportItem;
------------------------------ ENTITY DETAILS -------------------------------
@Override
entity Person {
   array ReportItemsArray(Id) to ReportItem(PersonId);
   array DayInfosArray(Id) to DayInfo(PersonId);
   array AttendanceItemsArray(Id) to AttendanceItem(PersonId);
}

Client

General syntax

stackedcalendar TimeReporting for Person {
    ...
    daysinfo for DayInfo using DayInfosArray {
        ...
    }
    reports for ReportItem using ReportItemsArray {
        ...
    }
    attendance for AttendanceItem using AttendanceItemsArray {
        ...
    }
    progressarea for AttendanceItem using AttendanceItemsArray {

    }
    ...
}

Main part top

Property Type Meaning Example
label String with interpolations The title of the stacked calendar "Time reporting for ${PersonName}"
weekstart Attribute An attribute containing a number specifying the day that starts the week 0 = Sunday, 1 = Monday etc. StartOfWeek
weeklength Attribute An attribute containing a number specifying how many days to show in the stacked calendar, typical values would be 5 (work week) and 7 (full week) WeekLength
minuteincrements Attribute An attribute containing a number specifying the minutes increments of the drag and drop functionality, a good value is 5 allowing to drag in 5 minute increments, typically would represent the minimum allowed report time increments MinutesIncrements
serverusesminutes boolean Was intended to allow the server to communicate time in hour format instead of the default minutes format, however it was never implemented on the client side, so for now the server needs to communicate in minutes, and this value should just be set to true [true]
#### Daysinfo part
Property Type Meaning Example
- - - -
date Attribute The attribute defining the date in the day ForDay
duration Attribute The attribute defining the schedule duration for the day, this value is however currently not used, schedule duration is controlls UI wise with the jobleft property ScheduleDuration
card CardName A card to show for this day DayInfoCard
cardindication Object with emphasises These emphasises defines the color of the card See below (same as for indication)
indication Object with emphasises These emphasises defines the color of the date See below
wageleft Attribute The attribute defining how much wage is left to report for this day. When wageleft is more than 0 the day is considered missing important attendance reports and will show a warning for that (in the daysinfo section and in the attendance stack) with a button to add attendance, this value is also used as a default value in the progressarea RemainingWage
jobleft Attribute The attribute defining how much job is left to report for this day. This is actually what controls the "To report" size of the stacked calendar days, this value is also used as a default value in the progressarea RemainingJob
statuses Each day can have a status shown as a label on a background emphasis color, this is controlled using expressions, the first truthy expression will win. See below
edit command Inline command With this command visible there will be a row below the stacks with a label and a clickable icon running the command, could be used for editing notes on the day See below
createreport command Inline command Command for creating a new report, will be called when clicking the button in the schedule part above the stack See below
createattendance command Inline command Command for creating a new attendance, will be placed below the main stack of the calendar. See below
##### Daysinfo statuses example
statuses {
         status "" {
            label = "Authorized";
            expression = [Status = "Authorized"];
            color = Complementary1;
         }
         status "" {
            label = "Confirmed";
            expression = [Status = "Confirmed"];
            color = Complementary2;
         }
         status "" {
            label = "Completed";
            expression = [Status = "Completed"];
            color = Complementary3;
         }
         status "" {
            label = "Not Completed";
            expression = [true];
         }
      }
Inline commands syntax and example
Property Type Meaning Example
label string with interpolations Label for the button that start the command, in stacked calendar this label is typically not part of the button but next to it.
icon string Name of an icon to use for the button that starts the command
visible Expression Expression that specifies if the label and icon will be visible at all
enabled Expression Expression that specifies if the icon will be clickable
execute Command execute block
edit command {
    icon = "document";
    label = "Edit Note";
    enabled = [Status = "Not Confirmed"];
    visible = [Status != "Authorized"];

    execute {
        dialog ModifyNoteDialog(PersonId, ForDay, Note) into(PersonId, ForDay, Note) {
            when OK {
                call ModifyNote(PersonId, ForDay, Note);
            }
        }
    }
}

Reports part

Property Type Meaning Example
date Attribute Attribute that specifies which day this report is for ForDay
duration Attribute Attribute that specifies the duration of this report JobMinutes
label String with interpolations The heading to use for this report "${Project}.${SubProject}.${Activity}"
description String with interpolations The description to use for this report "${Description}"
card Card Name A card to show for this report ReportCard
indication Object with emphasises Specifies the color of the corner indication of the report See below
grouping Specifies how different reports are grouped together when it comes to coloring See below
edit command Inline command Command shown on each report at the bottom meant for editing information of the report
delete command Inline command Command shown on each report at the bottom meant for deleting the report
copy command Inline command Command run when dragging a report from one day to another, using enable on this command will control if it is possible to copy by dragging
editduration command Inline command Command run when dragging the duration of a report, using enable on this command will control if it is possible to drag the duration at all
create command Inline command Deprecated in favor of the createreport command on the daysinfo part, still mandatory however, will be used if no createreport command is available on the daysinfo
##### Indication example
indication {
    emphasis Complementary3 = [Activity = "TIMEREP"];
    emphasis Complementary4 = [Activity = "A1"];
    emphasis Complementary5 = [true];
}
Grouping syntax and example
Property Type Meaning Example
primary Attribute plus emphasis The primary grouping controls the color of the event created, the emphasis specified specifies the specific colors, if the no emphasis evaluates to true, the attribute specified will be used to ensure all events of the same attribute value will ge the same color. See below
secondary Attribute plus emphasis The secondary grouping controls the color of the stripe to the left in the event, the emphasis specified specifies the specific colors, if the no emphasis evaluates to true, the attribute specified will be used to ensure all events of the same attribute value will ge the same color. See below
grouping {
    primary Project {
        emphasis Complementary1 = [Project = "Project1"];
        emphasis Complementary2 = [Project = "Project2"];
    }
    secondary SubProject {
        emphasis Complementary3 = [SubProject = "Sub1"];
        emphasis Complementary4 = [SubProject = "Sub2"];
        emphasis Complementary5 = [true];
    }
}

Attendance part

Property Type Meaning Example
date Attribute Attribute that specifies which day this attendance is for ForDay
duration Attribute Attribute that specifies the duration of this attendance WageMinutes
label String with interpolations The heading to use for this attendance "${WageType}"
description String with interpolations The description to use for this attendance "${Description}"
card Card Name A card to show for this attendance AttendanceCard
indication Object with emphasises Specifies the color of the corner indication of the report See above
grouping Specifies how different attendances are grouped together when it comes to coloring and when used as report types See example for reports
types Controlling which types of attendances to use where in the stacked calendar See below
edit command Inline command Command shown on each report type attendance or info meant for editing information of the attendance
delete command Inline command Command shown on each report type attendance or info meant for deleting the report
copy command Inline command Command run when dragging a report type attendance from one day to another, using enable on this command will control if it is possible to copy by dragging
editduration command Inline command Command run when dragging the duration of a report type attendance, using enable on this command will control if it is possible to drag the duration at all
create command Inline command Deprecated in favor of the createattendance command on the daysinfo part, still mandatory however, will be used if no createattendance command is available on the daysinfo
##### Types syntax and example
Property Type Meaning
- - - -
controlling Attribute The attribute to use for specifying different types WageType
report List of attribute values A list of the types to use as report types
wage List of attribute values and emphasises A list of the types to use as wage types meaning that they will be seen in the small stack to the right of the main stack, the emphasises controls which colors to use for the attendances when used there.
info List of attribute values A list of the types to show in the list at the bottom of each day.
types {
    controlling WageType;
    report Absence, BalanceWithdrawal;
    wage Absence, BalanceWithdrawal, Normal, Overtime, ExtraTime, BalanceAccural {
        emphasis Neutral = [Attendance.WageType = "Absence" or Attendance.WageType = "BalanceWithdrawal"];
        emphasis Complementary5 = [Attendance.WageType = "Normal"];
        emphasis Complementary9 = [Attendance.WageType = "Overtime" or Attendance.WageType = "ExtraTime" or Attendance.WageType = "BalanceAccural"];
    }
    info BalanceWithdrawal, Overtime, ExtraTime, BalanceAccural, Information, Increment;
}

Progressarea part syntax and example

Property | Type | Meaning -|-|-|-| label | String with interpolations | The label of the progress area controlling | Attribute | The attribute that contains the type values value | | Specifying a list of attribute values and their labels and colors (using emphasis), each value will be one grouping in the progress bar.

progressarea for AttendanceItem using AttendanceItemsArray {
      label = "Reported hours for week";
      controlling WageType;
      value Normal {
         label = "Normal";
         emphasis Complementary3 = [true];
      }
      value ExtraTime, Overtime {
         label = "Overtime";
         emphasis Complementary9 = [true];
      }
      value Absence, BalanceWithdrawal {
         label = "Absence";
         emphasis Default = [true];
      }
      value MissingWage {
         label = "Missing Wage";
         emphasis Complementary1 = [true];
      }
      value LeftToReport {
         label = "Left To Report";
         emphasis Complementary2 = [true];
      }
   }

Main part bottom

Property Type Meaning Example
command CommandName Commands that act on the entire week can be added here, they will get all the dayInfo for the selected week as inputs to be used with a bulkexecute
commandgroup Object with commands A group of commands
## Special use cases
---
### Controlling the week start date via exposed view state
---
The week start date can be set using the exposed view state variable in commands, it would look something like

set component.TimeReporting.Date = MyDate;

It can also be written in navigation links, then it looks like this:

navigate "page/StackedCalendar/TimeReporting?viewStates={'stackedcalendar:TimeReporting': {'date': '${MyDate}'}}";

Bind other controls to week start date


This can be done using a singleton as data source, a singleton requires an entityset returning exactly one row, and it can be populated using a function. Parameters to functions can be exposed view state variables which the stacked calendar has one called date. So lets see some code:

In the client file

singleton SummarySingleton for SummaryData {
}

page StackedCalendarPage using Persons {
   selector PersonSelector;
   singleton SummarySingleton using GetSummaryData(component.TimeReporting.Date);
   group SummaryGroup bind SummarySingleton;
   stackedcalendar TimeReporting;
}

group SummaryGroup for SummaryData {
    field Attribute1;
    ...
}

In the projection file

function GetSummaryData List<Structure(SummaryData)> {
   parameter DateFrom Date;
}

structure SummaryData {
   attribute Attribute1 Text;
   ...
}

In the plsvc file

FUNCTION Get_Summary_Data___(
   date_from_ IN DATE )  RETURN Summary_Data_Arr
IS
   rec_arr_ Summary_Data_Arr := Summary_Data_Arr();
   rec_ Summary_Data_Rec;
BEGIN
   -- Use date_from_ variable to fill rec_ with the needed values

   rec_arr_.extend;
   rec_arr_(rec_arr_.last):=rec_;
   RETURN rec_arr_;
END Get_In_Out_Date_Str___;