::*TSt={tasknr::!TaskNr// for generating unique form-id's
,activated::!Bool// if true activate task, if set as result task completed
,userId::!Int// id of user to which task is assigned
,workflowLink::!WorkflowLink// process table entry information
,staticInfo::!StaticInfo// info which does not change during a run
,html::!HtmlTree// accumulator for html code
,options::!Options// iData lifespan and storage format
,trace::!Maybe[Trace]// for displaying task trace
,hst::!HSt// iData state
}
::TaskNr:==[Int]// task nr i.j is adminstrated as [j,i]
::WorkflowLink:==!(Entry,ProcessIds)// entry in table together with unique id which is used for checking whether the reference is still valid
::Entry:==!Int
::ProcessIds:==!(!UserId,!ProcessNr,!WorkflowLabel)// user id, process id and name given to a workflow process; is used as unique identifier in process table
::UserId:==!Int// a user id of an iTask user must be a unique integer value
::ProcessNr:==!Int
::WorkflowLabel:==!String
::StaticInfo={currentUserId::UserId// id of application user
,threadTableLoc::!Lifespan// where to store the server thread table, default is Session
}
::HtmlTree=BTHtmlCode// simple code
|(@@:)infix0TaskNameHtmlTree// code with id of user attached to it
|(-@:)infix0UserIdHtmlTree// skip code with this id if it is the id of the user
|(+-+)infixl1HtmlTreeHtmlTree// code to be placed next to each other
|(+|+)infixl1HtmlTreeHtmlTree// code to be placed below each other
|DivCodeStringHtmlTree// code that should be labeled with a div, used for Ajax and Client technology
|isNothingtrace||taskname==""=(val,tst)// no trace, just return value
=(val,{tst&trace=Just(InsertTraceactivatedtasknruserIdoptionstaskname(printToStringval%(0,30))(fromJusttrace))})// adjust trace, don't print to long values
mkParSubTask::!String!Int(Taska)->(Taska)|iCreateAndPrinta// two shifts are needed
(<!) :: repeat task (as a loop) as long as predicate does not hold; also works for tasks that don't require any user interactions (e.g. database access)