implementation module Incidone.Util.TaskPatterns import iTasks, iTasks.Extensions.Dashboard import iTasks.UI.Definition import Incidone.OP.IncidentManagementTasks, Incidone.OP.ContactManagementTasks import Text, Data.Functor, Data.Either, Data.Maybe import qualified Data.Map as DM import Data.Map.GenJSON import StdMisc //FIXME /* fillNotes :: [(UIControl,UIAttributes)] -> [(UIControl,UIAttributes)] fillNotes cs = map fillNote cs where fillNote (c=:(UIEditNote _ _),a) = (fillHeight c,'DM'.newMap) fillNote x = x */ /** * Create a new incident containing no information at all. */ createNewIncident :: Task (Maybe IncidentNo) createNewIncident = enterInformation ("Create new incident", "Fill in the following basic information to create a new incident") [] >>? createIncident createNewContact :: Task (Maybe ContactNo) createNewContact = enterInformation ("New contact","Enter the basic information of the new contact") [] >>? createContact indexedStore :: String v -> SDSLens k v v | Eq k & Ord k & iTask k & iTask v indexedStore name def = sdsSplit "indexedStore" (\p -> ((),p)) read write (Just \p mapping. Ok (fromMaybe def ('DM'.get p mapping))) (sharedStore name 'DM'.newMap) where read p mapping = fromMaybe def ('DM'.get p mapping) write p mapping v = ('DM'.put p v mapping,const ((==) p)) sdsDeref :: (sds1 p [a] [a]) (a -> Int) (sds2 [Int] [b] x) ([a] [b] -> [c]) -> (SDSSequence p [c] [a]) | iTask p & TC a & TC b & TC c & TC x & RWShared sds1 & RWShared sds2 sdsDeref sds1 toRef sds2 merge = sdsSequence "sdsDeref" paraml paramr (\_ _ -> Right read) writel writer sds1 sds2 where paraml p = p paramr p r1 = map toRef r1 param _ r = (\_ r -> map toRef r) read (as,bs) = merge as bs writel = SDSWriteConst (\_ w -> Ok (Just w)) writer = SDSWriteConst (\_ _ -> Ok Nothing) viewDetails :: !d (sds1 () (Maybe i) ()) (sds2 i c c) (c -> v) -> Task (Maybe v) | toPrompt d & iTask i & iTask v & iTask c & RWShared sds1 & RWShared sds2 viewDetails desc sel target prj = viewSharedInformation desc [] (mapRead (fmap prj) (targetShare sel target)) where targetShare :: (sds1 () (Maybe i) ()) (sds2 i c c) -> SDSSequence () (Maybe c) () | iTask i & iTask c & RWShared sds1 & RWShared sds2 targetShare sel target = sdsSequence "viewDetailsSeq" id (\_ i -> i) (\_ _ -> Right snd) writel writer sel (valueShare target) where writel = SDSWriteConst (\_ _ -> Ok Nothing) writer = SDSWriteConst (\_ _ -> Ok Nothing) valueShare :: (sds1 i c c) -> SDSSelect (Maybe i) (Maybe c) () | iTask i & iTask c & RWShared sds1 valueShare target = sdsSelect "viewDetailsValue" param (SDSNotifyConst (\_ _ _ _-> False)) (SDSNotifyConst (\_ _ _ _-> False)) (constShare Nothing) (mapRead Just (toReadOnly target)) where param Nothing = Left () param (Just i) = Right i optionalNewOrOpen :: (String,Task ()) (String,i -> Task ()) Workspace (sds () (Maybe i) ()) -> Task () | iTask i & RWShared sds optionalNewOrOpen (newLabel,newTask) (openLabel,openTask) ws selection = forever ( watch selection >>* [OnAction (Action newLabel) (always (addToWorkspace (newTask <<@ InWindow) ws)) ,OnAction (Action openLabel) (ifValue isJust (\(Just c) -> addToWorkspace (doOrClose (openTask c)) ws)) ] ) doAddRemoveOpen :: (Task a) (r -> Task b) (r -> Task c) Workspace (sds () (Maybe r) w) -> Task () | iTask a & iTask b & iTask c & iTask r & RWShared sds & TC w doAddRemoveOpen add remove open ws selection = forever (watch selection >>* [OnAction (Action "/Add") (always (addToWorkspace add ws)) ,OnAction (Action "/Remove") (ifValue isJust (\(Just sel) -> addToWorkspace (remove sel) ws)) ,OnAction (Action "/Open") (ifValue isJust (\(Just sel) -> addToWorkspace (open sel) ws)) ] ) //Move to util viewAndEdit :: (Task a) (Task b) -> Task b | iTask a & iTask b viewAndEdit view edit = forever (view >>* [OnAction (Action "Edit") (always edit)]) //Move to common tasks viewOrEdit :: d (Shared sds a) (a a -> Task ()) -> Task () | toPrompt d & iTask a & RWShared sds viewOrEdit prompt s log = forever (view >>* [OnAction (Action "/Edit") (hasValue edit)]) @! () where view = viewSharedInformation prompt [] s edit old = updateInformation prompt [] old >>? \new -> set new s >>| log old new doOrClose :: (Task a) -> Task (Maybe a) | iTask a doOrClose task = ((task @ Just) -||- chooseAction [(ActionClose,Nothing)]) >>- return doOrCancel :: (Task a) -> Task (Maybe a) | iTask a doOrCancel task = (chooseAction [(ActionCancel,Nothing)] -||- (task @ Just)) >>- return //withHeader :: (Task a) (Task b) -> Task b | iTask a & iTask b //withHeader headerTask bodyTask // = ((headerTask <<@ ForceLayout) ||- (bodyTask <<@ ForceLayout)) <<@ (ArrangeWithSideBar 0 TopSide 50 False) withHeader :: (Task a) (Task b) -> Task b | iTask a & iTask b withHeader headerTask bodyTask = (headerTask ||- bodyTask ) //<<@ AfterLayout arrange //FIXME /* where arrange ui=:{UIDef|content=UIBlocks [header,body] actions,windows} # (hcontrol,_,_,_) = blockToControl header # (UIContainer sOpts iOpts=:{UIItemsOpts|items},_,_,_) = blockToContainer body # bcontrol = case items of [item] = UIContainer sOpts {UIItemsOpts|iOpts & items = [setHeight FlexSize item]} _ = UIContainer sOpts iOpts = {UIDef|content= UIBlock {UIBlock |attributes = header.UIBlock.attributes ,content = defaultItemsOpts [hcontrol,setHeight FlexSize bcontrol] ,actions = actions ,hotkeys = header.UIBlock.hotkeys ++ body.UIBlock.hotkeys ,size = defaultSizeOpts },windows = windows} arrange ui = ui */ viewNoSelection :: Task () viewNoSelection = viewTitle "Select..." @! () (>>?) infixl 1 :: !(Task a) !(a -> Task b) -> Task (Maybe b) | iTask a & iTask b (>>?) taska taskbf = step taska (const Nothing) [OnAction ActionCancel (always (return Nothing)) ,OnAction ActionOk (hasValue (\a -> taskbf a @ Just)) ,OnValue (ifStable (\a -> taskbf a @ Just)) ] oneOrAnother :: !d (String,Task a) (String,Task b) -> Task (Either a b) | toPrompt d & iTask a & iTask b oneOrAnother desc (labela,taska) (labelb,taskb) = updateChoice desc [ChooseFromCheckGroup ((!!) [labela,labelb])] [0,1] 0 <<@ ApplyLayout (setUIAttributes (heightAttr WrapSize)) >&> \s -> whileUnchanged s ( \choice -> case choice of Nothing = (viewInformation () [] "You have to make a choice" @? const NoValue) (Just 0) = (taska @ Left) (Just 1) = (taskb @ Right) ) enterMultiple :: !String !Int (Task a) -> Task [a] | iTask a enterMultiple action min task = parallel ([(Embedded, const t) \\ t <- repeatn min task] ++ [(Embedded,more)]) [] @? res where res (Value l _) = Value [v \\ (_,Value v _) <- l] (foldl allStable True l) allStable cur (_,Value _ s) = cur && s allStable cur _ = False more list = viewInformation () [] () >>* [OnAction (Action action) (always (appendTask Embedded more list >>| task))] manageSharedListWithDetails :: (Int -> Task ()) (Task Int) (Shared sds [Int]) -> Task () | RWShared sds manageSharedListWithDetails detailsTask addTask refsList //Not the best implementation, but good enough for now = get refsList >>- \initList -> parallel ([(Embedded, removeWhenStable (detailsTask i)) \\ i <- initList] ++ [(Embedded,add)]) [] @! () where add list = addTask >>- \i -> upd (\is -> is++[i]) refsList >>| appendTask Embedded add list >>| removeWhenStable (detailsTask i) list removeWhenStable t l = t >>* [OnValue (ifStable (\v -> get (taskListSelfId l) >>- \id -> removeTask id l @! v))] manageBackgroundTask :: !d !String !String (Task a) -> Task () | toPrompt d & iTask a manageBackgroundTask d identity title task = viewSharedInformation d [ViewAs (view title)] taskPid >^* [OnAction (Action "Start") (ifValue isNothing startTask) ,OnAction (Action "Stop") (ifValue isJust stopTask) ] @! () where view title t = let (color,statusmsg) = status t in (color,title +++ " is " +++ statusmsg) status Nothing = (LightOff,"not activated") status (Just (taskId,Unstable)) = (LightOnGreen,"running" <+++ taskId ) status (Just (_,Stable)) = (LightOnGreen,"stopped") status (Just (_,Exception _)) = (LightOnRed,"stopped with an error") taskPid = mapRead find (sdsFocus ("name",identity) taskInstancesByAttribute) where find instances = case [(instanceNo,value) \\ {TaskInstance|instanceNo,value,attributes} <- instances | hasName identity attributes] of [(i,v):_] = Just (TaskId i 0,v) _ = Nothing hasName name attributes = maybe False ((==) name) ('DM'.get "name" attributes) startTask _ = appendTask (NamedDetached identity defaultValue True) (removeWhenStable (task @! ())) topLevelTasks @! () stopTask (Just (taskId,_)) = removeTask taskId topLevelTasks @! () removeWhenStable t l = t >>* [OnValue (ifStable (\_ -> get (taskListSelfId l) >>- \id -> removeTask id l @? const NoValue))] syncNetworkChannel :: String Int String (String -> m) (m -> String) (Shared sds ([m],Bool,[m],Bool)) -> Task () | iTask m & RWShared sds syncNetworkChannel server port msgSeparator decodeFun encodeFun channel = tcpconnect server port channel {ConnectionHandlers|onConnect=onConnect,onData=onData,onShareChange=onShareChange,onDisconnect=onDisconnect} @! () where onConnect _ _ (received,receiveStopped,send,sendStopped) = (Ok "",if (not (isEmpty send)) (Just (received,False,[],sendStopped)) Nothing, map encodeFun send,False) onData newData acc (received,receiveStopped,send,sendStopped) # [acc:msgs] = reverse (split msgSeparator (concat [acc,newData])) # write = if (not (isEmpty msgs && isEmpty send)) (Just (received ++ map decodeFun (reverse msgs),receiveStopped,[],sendStopped)) Nothing = (Ok acc,write,map encodeFun send,False) onShareChange acc (received,receiveStopped,send,sendStopped) = (Ok acc,Nothing,[],False) onDisconnect l (received,receiveStopped,send,sendStopped) = (Ok l,Just (received,True,send,sendStopped)) consumeNetworkStream :: ([m] -> Task ()) (Shared sds ([m],Bool,[m],Bool)) -> Task () | iTask m & RWShared sds consumeNetworkStream processTask channel = ((watch channel >>* [OnValue (ifValue ifProcess process)]) >| if (isEmpty received) (return ()) (processTask received) @! receiveStopped empty :: ([m],Bool,[m],Bool) -> ([m],Bool,[m],Bool) empty (_,rs,s,ss) = ([],rs,s,ss)