{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.Connect.Conditions
( Condition(..)
, ConditionType(..)
, ConditionSource(..)
, JIRACondition(..)
, ConfluenceCondition(..)
, staticJiraCondition
, staticConfluenceCondition
, remoteCondition
, invertCondition
) where
import Data.Aeson
import Data.Connect.AesonHelpers
import Data.Connect.OrphanInstances ()
import GHC.Generics
import qualified Data.HashMap.Strict as HM
-- | A 'Condition' can be placed on an Atlassian Connect Module to cause it to display or not based on the result it
-- returns. For example, you can choose not to show a WebPanel if the user viewing the page is not logged in. Conditions
-- are very useful in curating when your modules will appear to your users.
--
-- The Atlassian Connect documentation describes conditions fully:
-- <https://developer.atlassian.com/static/connect/docs/concepts/conditions.html>
data Condition
-- | A single condition based on a source.
= SingleCondition
{ conditionSource :: ConditionSource -- ^ The source of this condition.
, conditionInverted :: Bool -- ^ If you should invert the condition. For example, only show if user is NOT logged in.
, conditionParams :: HM.HashMap String String -- ^ Extra parameters to pass with the condition to give it context.
}
-- | A condition that is the composition of one or more conditions. The 'ConditionType' decides the way in which the
-- conditions are composed
| CompositeCondition
{ subConditions :: [Condition] -- ^ The conditions that will be merged together.
, conditionType :: ConditionType -- ^ The way in which the conditions will be merged together.
}
deriving (Show)
-- | Turn a standard JIRA Condition into a regular 'Condition'.
staticJiraCondition :: JIRACondition -> Condition
staticJiraCondition c = SingleCondition { conditionSource = StaticJIRACondition c, conditionInverted = False, conditionParams = HM.empty }
-- | Turn a standard Confluence Condition into a regular 'Condition'.
staticConfluenceCondition :: ConfluenceCondition -> Condition
staticConfluenceCondition c = SingleCondition { conditionSource = StaticConfluenceCondition c, conditionInverted = False, conditionParams = HM.empty }
-- | Given a URI that defines a remote condition convert it into a regular 'Condition'.
remoteCondition :: String -> Condition
remoteCondition conditionLocation = SingleCondition { conditionSource = RemoteCondition conditionLocation, conditionInverted = False, conditionParams = HM.empty }
-- | Invert the given condition.
invertCondition :: Condition -> Condition
invertCondition c@(SingleCondition {}) = c { conditionInverted = not . conditionInverted $ c }
-- One application of DeMorgans law for composite conditions.
invertCondition (CompositeCondition cs ct) = CompositeCondition (fmap invertCondition cs) (invertConditionType ct)
invertConditionType :: ConditionType -> ConditionType
invertConditionType AndCondition = OrCondition
invertConditionType OrCondition = AndCondition
instance ToJSON Condition where
toJSON sc@(SingleCondition {}) = object
[ "condition" .= conditionSource sc
, "invert" .= conditionInverted sc
, "params" .= conditionParams sc
]
toJSON cc@(CompositeCondition {}) = object [ "conditions" .= subConditions cc, "type" .= conditionType cc]
-- | Composite Conditions can be joined together to behave as a single condition. The way that you can join them together
-- is decided by the condition type.
data ConditionType
= AndCondition -- ^ The boolean intersection of the conditions.
| OrCondition -- ^ The boolean union of the conditions.
deriving (Eq, Show)
instance ToJSON ConditionType where
toJSON AndCondition = String "AND"
toJSON OrCondition = String "OR"
-- | Conditions can be specified by the Host application or by the Atlassian Connect add-on itself. This means that the
-- source of the condition needs to be specified and that is what you can use this data type to do.
data ConditionSource
-- | A static JIRA condition.
= StaticJIRACondition JIRACondition
-- | A static Confluence condition.
| StaticConfluenceCondition ConfluenceCondition
-- | A remote condition defined by your Atlassian Connect application.
| RemoteCondition
{ remoteConditionPath :: String -- ^ The relative URI that you should hit in your Atlassian Connect application to
-- get the condition result. This URI, when hit, should return a JSON response in
-- the format:
--
-- > { "shouldDisplay": <true|false> }
}
deriving (Show, Eq)
instance ToJSON ConditionSource where
toJSON (StaticJIRACondition x) = toJSON x
toJSON (StaticConfluenceCondition x) = toJSON x
toJSON (RemoteCondition x) = toJSON x
-- The JIRA Conditions have been taken from:
-- https://developer.atlassian.com/static/connect/docs/modules/fragment/single-condition.html
-- as of the following date: Tue 23 Sep 2014 08:45:49 EST
-- Please update the date above whenever you update these conditions.
-- | The conditions that have been provided by JIRA. Please see the single condition documentation for more details:
-- <https://developer.atlassian.com/static/connect/docs/modules/fragment/single-condition.html>
data JIRACondition
= CanAttachFileToIssueJiraCondition
| CanManageAttachmentsJiraCondition
| FeatureFlagJiraCondition
| HasIssuePermissionJiraCondition
| HasProjectPermissionJiraCondition -- ^ Returns true if there is a selected project and the user has project admin to it.
| HasSelectedProjectPermissionJiraCondition
| HasSubTasksAvaliableJiraCondition
| HasVotedForIssueJiraCondition
| IsAdminModeJiraCondition
| IsIssueAssignedToCurrentUserJiraCondition
| IsIssueEditableJiraCondition
| IsIssueReportedByCurrentUserJiraCondition
| IsIssueUnresolvedJiraCondition
| IsSubTaskJiraCondition
| IsWatchingIssueJiraCondition
| LinkingEnabledJiraCondition
| SubTasksEnabledJiraCondition
| TimeTrackingEnabledJiraCondition
| UserHasIssueHistoryJiraCondition
| UserIsAdminJiraCondition
| UserIsLoggedInJiraCondition
| UserIsProjectAdminJiraCondition
| UserIsSysadminJiraCondition
| UserIsTheLoggedInUserJiraCondition
| VotingEnabledJiraCondition
| WatchingEnabledJiraCondition
deriving (Eq, Show, Generic)
instance ToJSON JIRACondition where
toJSON = toJSON . dropSuffixAndSnakeCase "JiraCondition" . show
-- | The conditions that have been provided by Confluence. Please see the single condition documentation for more details:
-- <https://developer.atlassian.com/static/connect/docs/modules/fragment/single-condition.html>
data ConfluenceCondition
= ActiveThemeConfluenceCondition
| CanEditSpaceStylesConfluenceCondition
| CanSignupConfluenceCondition
| ContentHasAnyPermissionsSetConfluenceCondition
| CreateContentConfluenceCondition
| EmailAddressPublicConfluenceCondition
| FavouritePageConfluenceCondition
| FavouriteSpaceConfluenceCondition
| FeatureFlagConfluenceCondition
| FollowingTargetUserConfluenceCondition
| HasAttachmentConfluenceCondition
| HasBlogPostConfluenceCondition
| HasPageConfluenceCondition
| HasSpaceConfluenceCondition
| HasTemplateConfluenceCondition
| LatestVersionConfluenceCondition
| NotPersonalSpaceConfluenceCondition
| PrintableVersionConfluenceCondition
| ShowingPageAttachmentsConfluenceCondition
| SpaceFunctionPermissionConfluenceCondition
| SpaceSidebarConfluenceCondition
| TargetUserCanSetStatusConfluenceCondition
| TargetUserHasPersonalBlogConfluenceCondition
| TargetUserHasPersonalSpaceConfluenceCondition
| ThreadedCommentsConfluenceCondition
| TinyUrlSupportedConfluenceCondition
| UserCanCreatePersonalSpaceConfluenceCondition
| UserCanUpdateUserStatusConfluenceCondition
| UserCanUseConfluenceConfluenceCondition
| UserFavouritingTargetUserPersonalSpaceConfluenceCondition
| UserHasPersonalBlogConfluenceCondition
| UserHasPersonalSpaceConfluenceCondition
| UserIsAdminConfluenceCondition
| UserIsConfluenceAdministratorConfluenceCondition
| UserIsLoggedInConfluenceCondition
| UserIsSysadminConfluenceCondition
| UserLoggedInEditableConfluenceCondition
| UserWatchingPageConfluenceCondition
| UserWatchingSpaceConfluenceCondition
| UserWatchingSpaceForContentTypeConfluenceCondition
| ViewingContentConfluenceCondition
| ViewingOwnProfileConfluenceCondition
deriving (Eq, Show, Generic)
instance ToJSON ConfluenceCondition where
toJSON = toJSON . dropSuffixAndSnakeCase "ConfluenceCondition" . show