feat(workflows): enum fields

This commit is contained in:
Gregor Kleen 2021-06-22 18:36:36 +02:00
parent aa1c0c8a3e
commit 426c40f0a4
6 changed files with 51 additions and 4 deletions

View File

@ -75,6 +75,8 @@ WorkflowEdgeFormFieldUserNotFound: E-Mail Adresse konnte keinem/keiner Benutzer:
WorkflowEdgeFormFieldMultipleNoneAdded: (Noch) keine Einträge WorkflowEdgeFormFieldMultipleNoneAdded: (Noch) keine Einträge
WorkflowEdgeFormFieldCaptureUserLabel: Aktuelle:r Benutzer:in WorkflowEdgeFormFieldCaptureUserLabel: Aktuelle:r Benutzer:in
WorkflowEdgeFormEnumFieldNothing: Keine Auswahl
WorkflowEdgeFormFieldDayTooFarPast offset@Integer: Datum liegt zu weit in der Vergangenheit (maximal #{offset} Tage) WorkflowEdgeFormFieldDayTooFarPast offset@Integer: Datum liegt zu weit in der Vergangenheit (maximal #{offset} Tage)
WorkflowEdgeFormFieldDayTooFarFuture offset@Integer: Datum liegt zu weit in der Zukunft (maximal #{offset} Tage) WorkflowEdgeFormFieldDayTooFarFuture offset@Integer: Datum liegt zu weit in der Zukunft (maximal #{offset} Tage)

View File

@ -34,6 +34,8 @@ WorkflowEdgeFormFieldUserNotFound: Email could not be resolved to an user
WorkflowEdgeFormFieldMultipleNoneAdded: No entries (yet) WorkflowEdgeFormFieldMultipleNoneAdded: No entries (yet)
WorkflowEdgeFormFieldCaptureUserLabel: Current user WorkflowEdgeFormFieldCaptureUserLabel: Current user
WorkflowEdgeFormEnumFieldNothing: No selection
WorkflowEdgeFormFieldDayTooFarPast offset: Date is too far in the past (maximum #{offset} days) WorkflowEdgeFormFieldDayTooFarPast offset: Date is too far in the past (maximum #{offset} days)
WorkflowEdgeFormFieldDayTooFarFuture offset: Date is too far in the future (maximum #{offset} days) WorkflowEdgeFormFieldDayTooFarFuture offset: Date is too far in the future (maximum #{offset} days)

View File

@ -29,7 +29,8 @@ import qualified Crypto.MAC.KMAC as Crypto
import qualified Crypto.Saltine.Class as Saltine import qualified Crypto.Saltine.Class as Saltine
import qualified Data.Binary as Binary import qualified Data.Binary as Binary
import qualified Data.ByteArray as BA import qualified Data.ByteArray as BA
import Crypto.Hash.Algorithms (SHAKE256) import Crypto.Hash.Algorithms (SHAKE128, SHAKE256)
import Crypto.MAC.KMAC (kmacGetDigest)
import qualified Control.Monad.State.Class as State import qualified Control.Monad.State.Class as State
import Control.Monad.Trans.RWS.Lazy (runRWST, mapRWST) import Control.Monad.Trans.RWS.Lazy (runRWST, mapRWST)
@ -330,7 +331,7 @@ workflowEdgePayloadFields specs = evalRWST (forM specs $ runExceptT . renderSpec
mNudge <- ask mNudge <- ask
case specField of case specField of
WorkflowPayloadFieldText{..} -> do WorkflowPayloadFieldText{..} | Nothing <- wpftPresets -> do
prev <- extractPrev @Text prev <- extractPrev @Text
wSetTooltip' (fmap slI18n wpftTooltip) $ wSetTooltip' (fmap slI18n wpftTooltip) $
f wpftOptional f wpftOptional
@ -340,6 +341,32 @@ workflowEdgePayloadFields specs = evalRWST (forM specs $ runExceptT . renderSpec
& maybe id (addName . ($ "text")) mNudge & maybe id (addName . ($ "text")) mNudge
) )
(prev <|> wpftDefault) (prev <|> wpftDefault)
WorkflowPayloadFieldText{..} | Just (otoList -> opts) <- wpftPresets -> do
prev <- extractPrev @Text
sBoxKey <- secretBoxKey
let offerNothing = wpftOptional || minLength 2 specs
optList = do
WorkflowPayloadTextPreset{..} <- opts
let optionExternalValue = toPathPiece @(Digest (SHAKE128 128)) . kmacGetDigest . kmaclazy ("payload-field-text-enum" :: ByteString) (Saltine.encode sBoxKey) $ Binary.encode optionInternalValue
optionInternalValue = wptpText
return ( Option
{ optionDisplay = slI18n wptpLabel
, ..
}
, toWidget . slI18n <$> wptpTooltip
)
readExternal = flip Map.lookup . Map.fromList $ map (views _1 (optionExternalValue &&& optionInternalValue)) optList
doExplainedSelectionField = has (folded . _wptpTooltip . _Just) opts
wSetTooltip' (fmap slI18n wpftTooltip) $
f wpftOptional
(bool (selectField' (guardOn offerNothing $ SomeMessage MsgWorkflowEdgeFormEnumFieldNothing) . return $ OptionList (optList ^.. folded . _1) readExternal)
(explainedSelectionField (guardOn offerNothing (SomeMessage MsgWorkflowEdgeFormEnumFieldNothing, Nothing)) $ return (optList, readExternal))
doExplainedSelectionField
)
( fsl (slI18n wpftLabel)
& maybe id (addName . ($ "text")) mNudge
)
(prev <|> wpftDefault <|> preview (_head . _1 . to optionInternalValue) optList)
WorkflowPayloadFieldNumber{..} -> do WorkflowPayloadFieldNumber{..} -> do
prev <- extractPrev @Scientific prev <- extractPrev @Scientific
wSetTooltip' (fmap slI18n wpfnTooltip) $ wSetTooltip' (fmap slI18n wpfnTooltip) $

View File

@ -17,6 +17,7 @@ module Model.Types.Workflow
, WorkflowPayloadSpec(..), _WorkflowPayloadSpec , WorkflowPayloadSpec(..), _WorkflowPayloadSpec
, WorkflowPayloadFieldReference , WorkflowPayloadFieldReference
, WorkflowPayloadTimeCapture, WorkflowPayloadTimeCapturePrecision(..) , WorkflowPayloadTimeCapture, WorkflowPayloadTimeCapturePrecision(..)
, WorkflowPayloadTextPreset(..)
, WorkflowPayloadField(..) , WorkflowPayloadField(..)
, WorkflowScope(..) , WorkflowScope(..)
, WorkflowScope'(..), classifyWorkflowScope , WorkflowScope'(..), classifyWorkflowScope
@ -255,6 +256,13 @@ data WorkflowPayloadTimeCapturePrecision
instance Default WorkflowPayloadTimeCapturePrecision where instance Default WorkflowPayloadTimeCapturePrecision where
def = WFCaptureDateTime def = WFCaptureDateTime
data WorkflowPayloadTextPreset = WorkflowPayloadTextPreset
{ wptpText :: Text
, wptpLabel :: I18nText
, wptpTooltip :: Maybe I18nHtml
} deriving (Eq, Ord, Read, Show, Generic, Typeable)
deriving anyclass (NFData)
-- Don't forget to update the NFData instance for every change! -- Don't forget to update the NFData instance for every change!
data WorkflowPayloadField fileid userid (payload :: Type) where data WorkflowPayloadField fileid userid (payload :: Type) where
WorkflowPayloadFieldText :: { wpftLabel :: I18nText WorkflowPayloadFieldText :: { wpftLabel :: I18nText
@ -263,6 +271,7 @@ data WorkflowPayloadField fileid userid (payload :: Type) where
, wpftDefault :: Maybe Text , wpftDefault :: Maybe Text
, wpftLarge :: Bool , wpftLarge :: Bool
, wpftOptional :: Bool , wpftOptional :: Bool
, wpftPresets :: Maybe (NonEmpty WorkflowPayloadTextPreset)
} -> WorkflowPayloadField fileid userid Text } -> WorkflowPayloadField fileid userid Text
WorkflowPayloadFieldNumber :: { wpfnLabel :: I18nText WorkflowPayloadFieldNumber :: { wpfnLabel :: I18nText
, wpfnPlaceholder :: Maybe I18nText , wpfnPlaceholder :: Maybe I18nText
@ -374,7 +383,7 @@ instance (Ord fileid, Ord userid, Typeable fileid, Typeable userid, Ord (FileFie
instance (NFData fileid, NFData userid, NFData (FileField fileid)) => NFData (WorkflowPayloadField fileid userid payload) where instance (NFData fileid, NFData userid, NFData (FileField fileid)) => NFData (WorkflowPayloadField fileid userid payload) where
rnf = \case rnf = \case
WorkflowPayloadFieldText{..} -> wpftLabel `deepseq` wpftPlaceholder `deepseq` wpftTooltip `deepseq` wpftDefault `deepseq` wpftLarge `deepseq` wpftOptional `deepseq` () WorkflowPayloadFieldText{..} -> wpftLabel `deepseq` wpftPlaceholder `deepseq` wpftTooltip `deepseq` wpftDefault `deepseq` wpftLarge `deepseq` wpftOptional `deepseq` wpftPresets `deepseq` ()
WorkflowPayloadFieldNumber{..} -> wpfnLabel `deepseq` wpfnPlaceholder `deepseq` wpfnTooltip `deepseq` wpfnDefault `deepseq` wpfnMin `deepseq` wpfnMax `deepseq` wpfnStep `deepseq` wpfnOptional `deepseq` () WorkflowPayloadFieldNumber{..} -> wpfnLabel `deepseq` wpfnPlaceholder `deepseq` wpfnTooltip `deepseq` wpfnDefault `deepseq` wpfnMin `deepseq` wpfnMax `deepseq` wpfnStep `deepseq` wpfnOptional `deepseq` ()
WorkflowPayloadFieldBool{..} -> wpfbLabel `deepseq` wpfbTooltip `deepseq` wpfbDefault `deepseq` wpfbOptional `deepseq` () WorkflowPayloadFieldBool{..} -> wpfbLabel `deepseq` wpfbTooltip `deepseq` wpfbDefault `deepseq` wpfbOptional `deepseq` ()
WorkflowPayloadFieldDay{..} -> wpfdLabel `deepseq` wpfdTooltip `deepseq` wpfdDefault `deepseq` wpfdOptional `deepseq` wpfdMaxPast `deepseq` wpfdMaxFuture `deepseq` () WorkflowPayloadFieldDay{..} -> wpfdLabel `deepseq` wpfdTooltip `deepseq` wpfdDefault `deepseq` wpfdOptional `deepseq` wpfdMaxPast `deepseq` wpfdMaxFuture `deepseq` ()
@ -830,6 +839,10 @@ deriveJSON defaultOptions
pathPieceJSON ''WorkflowPayloadTimeCapturePrecision pathPieceJSON ''WorkflowPayloadTimeCapturePrecision
deriveJSON defaultOptions
{ fieldLabelModifier = camelToPathPiece' 1
} ''WorkflowPayloadTextPreset
instance (FromJSON userid, Ord userid) => FromJSON (WorkflowNodeMessage userid) where instance (FromJSON userid, Ord userid) => FromJSON (WorkflowNodeMessage userid) where
parseJSON = genericParseJSON workflowNodeMessageAesonOptions parseJSON = genericParseJSON workflowNodeMessageAesonOptions
instance (FromJSON userid, Ord userid) => FromJSON (WorkflowEdgeMessage userid) where instance (FromJSON userid, Ord userid) => FromJSON (WorkflowEdgeMessage userid) where
@ -927,6 +940,7 @@ instance (ToJSON fileid, ToJSON userid, ToJSON (FileField fileid)) => ToJSON (Wo
, "default" JSON..= wpftDefault , "default" JSON..= wpftDefault
, "large" JSON..= wpftLarge , "large" JSON..= wpftLarge
, "optional" JSON..= wpftOptional , "optional" JSON..= wpftOptional
, "presets" JSON..= wpftPresets
] ]
toJSON WorkflowPayloadFieldNumber{..} = JSON.object $ omitNothing toJSON WorkflowPayloadFieldNumber{..} = JSON.object $ omitNothing
[ "tag" JSON..= WPFNumber' [ "tag" JSON..= WPFNumber'
@ -1007,6 +1021,7 @@ instance ( FromJSON fileid, FromJSON userid
wpftDefault <- o JSON..:? "default" wpftDefault <- o JSON..:? "default"
wpftLarge <- o JSON..:? "large" JSON..!= False wpftLarge <- o JSON..:? "large" JSON..!= False
wpftOptional <- o JSON..: "optional" wpftOptional <- o JSON..: "optional"
wpftPresets <- o JSON..:? "presets"
return $ WorkflowPayloadSpec WorkflowPayloadFieldText{..} return $ WorkflowPayloadSpec WorkflowPayloadFieldText{..}
WPFNumber' -> do WPFNumber' -> do
wpfnLabel <- o JSON..: "label" wpfnLabel <- o JSON..: "label"

View File

@ -260,6 +260,7 @@ makeLenses_ ''WorkflowScope
makeLenses_ ''WorkflowInstance makeLenses_ ''WorkflowInstance
makeLenses_ ''WorkflowInstanceDescription makeLenses_ ''WorkflowInstanceDescription
makeLenses_ ''WorkflowWorkflow makeLenses_ ''WorkflowWorkflow
makeLenses_ ''WorkflowPayloadTextPreset
makeLenses_ ''WorkflowGraph makeLenses_ ''WorkflowGraph
makeLenses_ ''WorkflowGraphNode makeLenses_ ''WorkflowGraphNode