Commit 53687986 authored by ecrombag's avatar ecrombag

- Refactoring of gVerify. It now also checks for blank (unmasked) values and...

- Refactoring of gVerify. It now also checks for blank (unmasked) values and shows an error icon behind required values.
- Bugfixes in the parallel combinator: Subtask-workers were not removed in case their task was reassigned to someone else. Changed the task-service, allowing it to accept result request for task numbers which do not equal processId's as the result of a parallel subtask is kept in a finished-task node, beneath the main-task node.
- Added sorting to the user-list returned by the user-service


git-svn-id: https://svn.cs.ru.nl/repos/iTask-system/trunk@1117 63da3aa8-80fd-4f01-9db8-e6ea747a3da2
parent 3908ef71
......@@ -46,8 +46,8 @@ itasks.ResultPanel = Ext.extend(itasks.RemoteDataPanel, {
this.properties = props;
this.setTitle(Ext.util.Format.ellipsis(subject,10));
rh.setContent(props.systemProperties.taskId, subject, props);
rh.setContent(data.tui.taskId, subject, props);
if(rp.initialized){
rp.removeAll();
......
......@@ -27,6 +27,9 @@ itasks.ttc.FormContainer = Ext.extend(itasks.ttc.InteractionBase, {
update: function(data) {
if(data.updates) {
//clear the form from any hints and errors
this.clearErrorsNHints();
var num = data.updates.length;
for (i = 0; i < num; i++) {
var update = data.updates[i];
......@@ -61,7 +64,7 @@ itasks.ttc.FormContainer = Ext.extend(itasks.ttc.InteractionBase, {
if(ct && ct.setHint) ct.setHint(update[2]);
break;
}
}
}
} else {
//Completely replace form
this.taskId = data.taskId;
......@@ -185,6 +188,17 @@ itasks.ttc.FormContainer = Ext.extend(itasks.ttc.InteractionBase, {
if(newTb)
tb.add(newTb);
this.setupToolbar(tb);
},
clearErrorsNHints : function(){
var f = function(ct){
if(ct.setHint) ct.setHint(''); //empty string == clear
if(ct.setError) ct.setError('');
return true;
}
this.panel.cascade(f);
}
});
......@@ -198,7 +212,7 @@ itasks.ttc.form.FormPanel = Ext.extend(Ext.Panel, {
{ unstyled: true
, cls: 'FormPanel'
, width: 720
, layout: 'auto'
, layout: 'form'
, autoScroll: true
});
......
......@@ -103,7 +103,7 @@ itasks.ttc.ParallelContainer = Ext.extend(Ext.Panel, {
handleDblClick : function(grid,row,e){
var rec = grid.getStore().getAt(row);
var taskId = rec.data.taskId;
var taskId = rec.data.taskId+'.0'; //add one shift as the result node is stored as a child of the process node
var finished = rec.data.finished;
if(finished){
......@@ -151,7 +151,7 @@ itasks.ttc.parallel.AssignWindow = Ext.extend(Ext.Window,{
this.progress = new Ext.ProgressBar({hidden: true});
Ext.apply(this,{
title: 'test',
title: 'Re-assign task',
modal: true,
resizable: false,
items: [{
......
......@@ -11,7 +11,7 @@ itasks.tui.BoolControl = Ext.extend(Ext.form.Checkbox,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
// this.allowBlank = this.optional;
this.checked = this.value == "True";
if(this.value == "") delete this.value;
......
......@@ -12,7 +12,7 @@ itasks.tui.CharControl = Ext.extend(Ext.form.TextField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
if(this.value == "") delete this.value;
itasks.tui.CharControl.superclass.initComponent.apply(this,arguments);
},
......
......@@ -17,7 +17,7 @@ itasks.tui.CurrencyControl = Ext.extend(Ext.form.TextField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
if(this.value == "") delete this.value;
itasks.tui.CurrencyControl.superclass.initComponent.apply(this,arguments);
},
......
......@@ -11,7 +11,7 @@ itasks.tui.DateControl = Ext.extend(Ext.form.DateField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
itasks.tui.DateControl.superclass.initComponent.apply(this,arguments);
},
......
......@@ -5,7 +5,7 @@ itasks.tui.FormattedTextControl = Ext.extend(Ext.form.HtmlEditor,{
Ext.apply(this, {
hideLabel: this.fieldLabel == null,
fieldLabel: itasks.util.fieldLabel(this.optional, this.fieldLabel),
allowBlank: this.optional,
// allowBlank: this.optional,
width: 700,
height: 300,
// ids for selection marker elements
......
......@@ -10,7 +10,7 @@ itasks.tui.IntControl = Ext.extend(Ext.form.NumberField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
// this.allowBlank = this.optional;
this.msgTarget = 'side';
......
......@@ -13,7 +13,7 @@ itasks.tui.NoteControl = Ext.extend(Ext.form.TextArea,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
if(this.value == "") delete this.value;
itasks.tui.NoteControl.superclass.initComponent.apply(this,arguments);
},
......
......@@ -13,7 +13,7 @@ itasks.tui.PasswordControl = Ext.extend(Ext.form.TextField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
this.inputType = 'password';
if(this.value == "") delete this.value;
......
......@@ -13,7 +13,7 @@ itasks.tui.RealControl = Ext.extend(Ext.form.NumberField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
if(this.value == "") delete this.value;
itasks.tui.RealControl.superclass.initComponent.apply(this,arguments);
},
......
......@@ -11,7 +11,8 @@ itasks.tui.StringControl = Ext.extend(Ext.form.TextField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
this.allowBlank = true;
if(this.value == "") delete this.value;
itasks.tui.StringControl.superclass.initComponent.apply(this,arguments);
},
......
......@@ -8,7 +8,7 @@ itasks.tui.common.markError = function(field,msg){
var mt = field.getMessageHandler();
if(mt && mt.markHint){
if(mt && mt.markError){
mt.markError(field, msg);
}else if(field.errorTarget){
var t = Ext.getDom(field.errorTarget);
......@@ -128,7 +128,7 @@ Ext.apply(Ext.form.MessageTargets.side, {
},
markHint : function(field, msg){
if(!this.activeError && !field.hintIcon){
if(!field.hintIcon){
var elp = field.getErrorCt();
if(!elp){
......
......@@ -12,7 +12,7 @@ itasks.tui.TimeControl = Ext.extend(Ext.form.TimeField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
if(this.value == "") delete this.value;
itasks.tui.TimeControl.superclass.initComponent.apply(this,arguments);
},
......
......@@ -35,7 +35,7 @@ itasks.tui.UsernameControl = Ext.extend(Ext.form.ComboBox,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
//this.allowBlank = this.optional;
if(this.value == "") delete this.value;
itasks.tui.UsernameControl.superclass.initComponent.apply(this,arguments);
},
......
......@@ -515,13 +515,13 @@ div.taskForestLegend{
}
.list-item-light {
padding: 4px 5px 2px 0px;
padding: 4px 8px 2px 0px;
background-image: url('img/light-blue-background.png') !important;
position: relative;
}
.list-item-dark {
padding: 4px 6px 2px 0px;
padding: 4px 8px 2px 0px;
background-image: url('img/dark-blue-background.png') !important;
position: relative;
}
......@@ -816,3 +816,6 @@ button.x-form-document-trash-icon {
display: none;
}
......@@ -338,7 +338,11 @@ addSubTaskWorker procId user mbpartype tst
= case mbpartype of
Nothing = tst
(Just Closed) = tst
(Just Open) = {TSt | tst & properties = {tst.TSt.properties & systemProperties = {tst.TSt.properties.systemProperties & subTaskWorkers = removeDup [(procId,user):tst.TSt.properties.systemProperties.subTaskWorkers]}}}
(Just Open) = {TSt | tst & properties =
{tst.TSt.properties & systemProperties =
{tst.TSt.properties.systemProperties & subTaskWorkers =
//filter the process from the current list of subtask workers before adding, as there can be only one worker on a subtask.
removeDup [(procId,user):(filter (\(pid,_) -> pid <> procId) tst.TSt.properties.systemProperties.subTaskWorkers)]}}}
removeSubTaskWorker :: !ProcessId !User !(Maybe TaskParallelType) !*TSt -> *TSt
removeSubTaskWorker procId user mbpartype tst
......
......@@ -11,8 +11,8 @@ derive gVisualize EmailAddress, DateTime
derive gUpdate EmailAddress, Note, DateTime
derive gMerge EmailAddress, Password, Note, Date, Time, DateTime, Currency, FormButton, ButtonState
derive gLexOrd Currency
derive gError EmailAddress, Password, Note, Date, Time, DateTime, Currency, FormButton, ButtonState
derive gHint EmailAddress, Password, Note, Date, Time, DateTime, Currency, FormButton, ButtonState
derive gError EmailAddress, DateTime
derive bimap Maybe, (,)
......@@ -63,7 +63,7 @@ gVisualize{|Password|} old new vst=:{vizType,label,idPrefix,currentPath,useLabel
= (upd++msg
, {VSt | vst & currentPath = stepDataPath currentPath, valid = stillValid currentPath errorMask new optional valid})
_
= ([TextFragment (foldr (+++) "" (repeatn (size oldV) "*"))],{VSt | vst & currentPath = stepDataPath currentPath, valid = stillValid currentPath errorMask old optional valid})
= ([TextFragment (foldr (+++) "" (repeatn 8 "*"))],{VSt | vst & currentPath = stepDataPath currentPath, valid = stillValid currentPath errorMask old optional valid})
where
id = dp2id idPrefix currentPath
oldV = value2s currentPath old
......@@ -170,6 +170,7 @@ where
id = dp2id idPrefix currentPath
//******************************************************************************************************************************************
gUpdate{|FormButton|} _ ust=:{USt|mode=UDCreate}
= ({FormButton | label = "Form Button", icon="", state = NotPressed}, ust)
......@@ -238,6 +239,34 @@ gUpdate{|Currency|} s ust=:{USt|mode=UDMask,currentPath,mask}
= (s, {USt|ust & currentPath = stepDataPath currentPath, mask = appendToMask currentPath mask})
gUpdate{|Currency|} s ust = (s,ust)
//******************************************************************************************************************************************
gError{|FormButton|} _ est=:{ESt | currentPath} = {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Password|} _ est=:{ESt | currentPath}
# est = verifyIfBlank currentPath currentPath est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Date|} _ est=:{ESt | currentPath}
# est = verifyIfBlank currentPath currentPath est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Time|} _ est=:{ESt | currentPath}
# est = verifyIfBlank currentPath currentPath est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Currency|} _ est=:{ESt | currentPath}
# est = verifyIfBlank currentPath currentPath est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Note|} _ est=:{ESt | dataMask,errorMask,currentPath}
# est = if (isMember (shiftLabeledDataPath currentPath) (toLabeledMask dataMask))
est
({ESt | est & errorMask = [(currentPath, MPAlways, IsBlankError):errorMask]})
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
//******************************************************************************************************************************************
currentTime :: !*World -> (!Time,!*World)
currentTime world
# (tm,world) = localTime world
......
......@@ -10,8 +10,9 @@ derive gParse GoogleMap, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapTyp
derive gVisualize GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType
derive gUpdate GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive gMerge GoogleMap, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive gError GoogleMap, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive gHint GoogleMap, GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive gError GoogleMapMarker, GoogleMapInfoWindow, GoogleMapType, GoogleStaticMap
derive bimap Maybe, (,)
......@@ -55,6 +56,8 @@ where
toString HYBRID = "HYBRID"
toString TERRAIN = "TERRAIN"
gError{|GoogleMap|} _ est = (stepOut est)
gVisualize {|GoogleMap|} old new vst=:{vizType, label, idPrefix, currentPath, valid, optional, useLabels}
= case vizType of
VEditorDefinition = ([TUIFragment (TUICustom ((mapPanel old (label2s optional label) (not useLabels) idPrefix currentPath True)))],{VSt | vst & currentPath = stepDataPath currentPath })
......
......@@ -67,6 +67,7 @@ where
getProcess :: !TaskId !*st -> (!Maybe Process, !*st)
getProcessForUser :: !User !TaskId !*st -> (!Maybe Process, !*st)
getProcessForManager :: !User !TaskId !*st -> (!Maybe Process, !*st)
getProcessForTask :: !TaskId !*st -> (!Maybe Process, !*st)
getProcesses :: ![TaskStatus] !*st -> (![Process], !*st)
getProcessesById :: ![TaskId] !*st -> (![Process], !*st)
getProcessesForUser :: !User ![TaskStatus] !*st -> (![Process], !*st)
......
......@@ -80,6 +80,20 @@ where
where
relevantProc targetId {Process|taskId} = taskId == targetId
relevantProc _ _ = False
//Finds process for task if taskId <> procId
getProcessForTask :: !TaskId !*IWorld -> (!Maybe Process, !*IWorld)
getProcessForTask taskId iworld
# taskNr = taskNrFromString taskId
# (procs,iworld) = processStore id iworld
= (findProc taskNr procs, iworld)
where
findProc [] procs = Nothing
findProc taskNr procs
# taskId = taskNrToString taskNr
# fproc = filter (\p -> p.Process.taskId == taskId) procs
| not (isEmpty fproc) = Just (hd fproc)
= findProc (tl taskNr) procs
getProcesses :: ![TaskStatus] !*IWorld -> (![Process], !*IWorld)
getProcesses statusses iworld
......@@ -206,6 +220,8 @@ where
getProcessForUser user processId tst = accIWorldTSt (getProcessForUser user processId) tst
getProcessForManager :: !User !TaskId !*TSt -> (!Maybe Process,!*TSt)
getProcessForManager manager processId tst = accIWorldTSt (getProcessForManager manager processId) tst
getProcessForTask :: !TaskId !*TSt -> (!Maybe Process, !*TSt)
getProcessForTask taskId tst = accIWorldTSt (getProcessForTask taskId) tst
getProcesses :: ![TaskStatus] !*TSt -> (![Process],!*TSt)
getProcesses statuses tst = accIWorldTSt (getProcesses statuses) tst
getProcessesById :: ![TaskId] !*TSt -> (![Process],!*TSt)
......
......@@ -5,7 +5,7 @@ import GenUpdate
:: LabelOrNumber = Unlabeled Int | Label String
:: MessagePredicate = MPIfMasked | MPAlways
:: ErrorMessage :== String
:: ErrorMessage = ErrorMessage String | IsBlankError
:: HintMessage :== String
:: ErrorMask :== [(LabeledDataPath, MessagePredicate, ErrorMessage)]
......@@ -23,6 +23,8 @@ import GenUpdate
, currentPath :: LabeledDataPath
}
instance == LabelOrNumber
generic gError a :: a *ESt -> *ESt
generic gHint a :: (Maybe a) *HSt -> *HSt
......@@ -49,7 +51,20 @@ where
instance VerifyState HSt
instance VerifyState ESt
/*
* Checks if the value is masked and adds an appropriate error if this is not the case
*
* @param The path in the mask which needs to be checked for the value
* @param The path to the interface component to which the error needs to be applied
* @param The Error State
*
* @return The modified Error State
*/
verifyIfBlank :: !LabeledDataPath !LabeledDataPath !*ESt -> *ESt
getErrorMessage :: DataPath DataMask ErrorMask -> String
getHintMessage :: DataPath DataMask HintMask -> String
getErrorCount :: DataPath DataMask ErrorMask -> Int
\ No newline at end of file
getErrorCount :: DataPath DataMask ErrorMask -> Int
toLabeledMask :: !DataMask -> [LabeledDataPath]
\ No newline at end of file
......@@ -17,6 +17,12 @@ where
(==) (Label a) (Label b) = a == b
(==) _ _ = False
instance == ErrorMessage
where
(==) (ErrorMessage a) (ErrorMessage b) = a == b
(==) (IsBlankError) (IsBlankError) = True
(==) _ _ = False
mkHSt :: *HSt
mkHSt = {HSt | dataMask = [], hintMask = [], currentPath = shiftLabeledDataPath []}
......@@ -42,15 +48,25 @@ gError{|OBJECT of d|} fx (OBJECT x) est=:{ESt | currentPath}
# est = fx x est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|CONS of d|} fx (CONS x) est=:{ESt | currentPath}
# est = fx x {ESt | est & currentPath = shiftLabeledDataPath currentPath}
# est = if(d.gcd_arity > 0 || not (isEmpty d.gcd_fields))
(fx x {ESt | est & currentPath = shiftLabeledDataPath currentPath})
est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|FIELD of d|}fx (FIELD x) est = fx x est
gError{|Int|} _ est=:{ESt | currentPath}
# est = verifyIfBlank currentPath currentPath est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Real|} _ est=:{ESt | currentPath}
# est = verifyIfBlank currentPath currentPath est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Char|} _ est=:{ESt | currentPath}
# est = verifyIfBlank currentPath currentPath est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Bool|} _ est=:{ESt | currentPath}
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|String|} _ est=:{ESt | currentPath}
# est = verifyIfBlank currentPath currentPath est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|FIELD of d|} fx (FIELD x) est = fx x est
gError{|Int|} _ est=:{ESt | currentPath} = {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Real|} _ est=:{ESt | currentPath} = {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Char|} _ est=:{ESt | currentPath} = {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Bool|} _ est=:{ESt | currentPath} = {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|String|} _ est=:{ESt | currentPath} = {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|(,)|} f1 f2 (x1,x2) est=:{ESt | currentPath}
# est = f1 x1 {ESt | est & currentPath = shiftLabeledDataPath currentPath}
......@@ -68,8 +84,10 @@ gError{|(,,,)|} f1 f2 f3 f4 (x1,x2,x3,x4) est=:{ESt | currentPath}
# est = f4 x4 est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|[]|} fx l est=:{ESt | currentPath}
# est = checkItems fx l {ESt | est & currentPath = shiftLabeledDataPath currentPath}
gError{|[]|} fx l est=:{ESt | currentPath, errorMask}
# est = if (isEmpty l)
({ESt | est & errorMask = [(currentPath,MPAlways,IsBlankError):errorMask]})
(checkItems fx l {ESt | est & currentPath = shiftLabeledDataPath currentPath})
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
where
checkItems fx [] est = est
......@@ -78,8 +96,10 @@ where
gError{|Maybe|} fx Nothing est=:{ESt | currentPath}
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
gError{|Maybe|} fx (Just x) est=:{ESt | currentPath}
# est = fx x est
= {ESt | est & currentPath = stepLabeledDataPath currentPath}
# est=:{ESt | errorMask} = fx x est
//Filter all 'blank' errors from the component directly below the maybe, as it is allowed to be empty (e.g. [])
# errorMask = filter (\(path,_,msg) -> (not (path == currentPath && msg == IsBlankError))) errorMask
= {ESt | est & currentPath = stepLabeledDataPath currentPath, errorMask = errorMask}
gError{|Dynamic|} x est=:{ESt | currentPath} = {ESt | est & currentPath = stepLabeledDataPath currentPath}
......@@ -147,7 +167,7 @@ gHint{|Dynamic|} x hst=:{HSt | currentPath} = {HSt | hst & currentPath = stepLab
//Utility functions
appendError :: !String !MessagePredicate *ESt -> *ESt
appendError err pred est=:{ESt | currentPath,errorMask}
= {ESt | est & errorMask = [(currentPath,pred,err):errorMask]}
= {ESt | est & errorMask = [(currentPath,pred,ErrorMessage err):errorMask]}
appendHint :: !String !MessagePredicate *HSt -> *HSt
appendHint hint pred hst=:{HSt | currentPath,hintMask}
......@@ -205,7 +225,7 @@ dp2ldp :: DataPath -> LabeledDataPath
dp2ldp dp = [Unlabeled i \\ i <- dataPathList dp]
getErrorMessage :: DataPath DataMask ErrorMask -> String
getErrorMessage dp dmask mmask = join ", " [s \\ (ldp,p,s) <- mmask | eqPath (dataPathList dp) ldp && predValid ldp p dmask]
getErrorMessage dp dmask mmask = join ", " [toString s \\ (ldp,p,s) <- mmask | eqPath (dataPathList dp) ldp && predValid ldp p dmask]
getHintMessage :: DataPath DataMask HintMask -> String
getHintMessage dp dmask mmask = join ", " [s \\ (ldp,p,s) <- mmask | eqPath (dataPathList dp) ldp && predValid ldp p dmask]
......@@ -215,9 +235,22 @@ getErrorCount dp dmask mmask = length [s \\ (ldp,p,s) <- mmask | eqPath (dataPat
predValid :: LabeledDataPath MessagePredicate DataMask -> Bool
predValid ldp MPAlways dm = True
predValid ldp MPIfMasked dm = isMember ldp [[Unlabeled i \\ i<-dp] \\ dp <- dm]
predValid ldp MPIfMasked dm = isMember ldp [[Unlabeled i \\ i <- dp] \\ dp <- dm]
eqPath :: [Int] [LabelOrNumber] -> Bool
eqPath [] [] = True
eqPath [i:ix] [(Unlabeled l):lx] = i == l && eqPath ix lx
eqPath _ _ = False
\ No newline at end of file
eqPath _ _ = False
verifyIfBlank :: !LabeledDataPath !LabeledDataPath !*ESt -> *ESt
verifyIfBlank valuePath errorPath est=:{ESt | errorMask,dataMask}
| not (isMember valuePath [map (\i -> Unlabeled i) m \\ m <- dataMask]) = {ESt | est & errorMask = [(errorPath, MPAlways, IsBlankError):errorMask]}
| otherwise = est
toLabeledMask :: !DataMask -> [LabeledDataPath]
toLabeledMask dm = [map (\i -> Unlabeled i) m \\ m <- dm]
instance toString ErrorMessage
where
toString (ErrorMessage s) = s
toString IsBlankError = "This value is required"
\ No newline at end of file
......@@ -65,8 +65,8 @@ derive bimap VisualizationValue
//Utility functions making specializations of gVisualize
instance toString (VisualizationValue a) | toString a
getHintUpdate :: TUIId DataPath DataMask HintMask -> Visualization
getErrorUpdate :: TUIId DataPath DataMask ErrorMask -> Visualization
getHintUpdate :: TUIId DataPath DataMask HintMask -> [Visualization]
getErrorUpdate :: TUIId DataPath DataMask ErrorMask -> [Visualization]
getErrorNHintMessages :: !DataMask !*VSt -> (String, String, *VSt)
updateErrorNHintMessages :: !DataMask !*VSt -> ([Visualization], *VSt)
......
This diff is collapsed.
......@@ -139,19 +139,20 @@ taskService url html path req tst
//taskId/result -> show result of a finished in serialized form (to be implemented)
//Show the result of a finished task as interface definition
//TODO: Prevent access in case of a faulty user
[taskId,"result","tui"]
| isJust mbSessionErr
| isJust mbSessionErr
= (serviceResponse html "task result user interface" url tuiParams (jsonSessionErr mbSessionErr), tst)
# (mbProcess, tst) = getProcess taskId tst
= case mbProcess of
Nothing
= (notFoundResponse req, tst)
Just proc
# task = taskItem proc
# (tree,tst) = calculateTaskTree taskId [] tst
# tui = buildResultPanel tree
# json = JSONObject [("success",JSONBool True),("task",toJSON task),("tui",toJSON tui)]
= (serviceResponse html "task result user interface" url tuiParams json, tst)
# (mbProcess, tst) = getProcessForTask taskId tst
= case mbProcess of
Nothing
= (notFoundResponse req, tst)
Just proc
# task = taskItem proc
# (tree,tst) = calculateTaskResult taskId tst
# tui = buildResultPanel tree
# json = JSONObject [("success",JSONBool True),("task",toJSON task),("tui",toJSON tui)]
= (serviceResponse html "task result user interface" url tuiParams json, tst)
_
= (notFoundResponse req, tst)
where
......
......@@ -3,6 +3,7 @@ implementation module UserService
import Http, TSt
import HtmlUtil
import UserDB
import StdOrdList
derive JSONEncode UserDetails, Password
......@@ -25,7 +26,7 @@ userService url html path req tst
| isJust mbSessionErr
= (serviceResponse html "users names" url params (jsonSessionErr mbSessionErr), tst)
# (users,tst) = getUsers tst
# json = JSONObject [("success",JSONBool True),("users",toJSON [toString u \\ u <- users])]
# json = JSONObject [("success",JSONBool True),("users",toJSON (sort [toString u \\ u <- users]))]
= (serviceResponse html "users names" url params json, tst)
//Show user details
[userId]
......
......@@ -165,6 +165,16 @@ applyChangeToTaskTree :: !ProcessId !ChangeInjection !*TSt -> *TSt
*/
calculateTaskTree :: !TaskId ![TaskEvent] !*TSt -> (!TaskTree, !*TSt)
/**
* Render resultpanel from a task which is not process
*
* @param The task id
* @param The task state
*
* @ return The task tree
* @ return The modified task state
**/
calculateTaskResult :: !TaskId !*TSt -> (!TaskTree, !*TSt)
/**
* Calculates all task trees
*
* @param The value updates to apply
......
......@@ -501,6 +501,30 @@ applyChangeToTaskTree pid (lifetime,change) tst=:{taskNr,taskInfo,tree,staticInf
Nothing
= tst
calculateTaskResult :: !TaskId !*TSt -> (!TaskTree, !*TSt)
calculateTaskResult taskId tst