module IHP.IDE.Data.View.Layout ( customQuery , tableHead , renderRows , sqlValueToText , renderId , isBoolField , isSqlFunction , isSqlFunction_ , fillField , getColDefaultValue , renderRowValue , renderDefaultWithoutType , isBooleanParam , headerNav ) where import IHP.ViewPrelude import IHP.IDE.ToolServer.Types import IHP.IDE.ToolServer.Routes import qualified Data.Text as Text import IHP.IDE.ToolServer.Helper.View customQuery :: Text -> Html customQuery :: Text -> Html customQuery Text input = [hsx|<div class="p-2 rounded mt-2" style="background-color: #002B36;"><div id="queryInput" style="height:16px">{input}</div></div>|] tableHead :: [[DynamicField]] -> Text -> Html tableHead :: [[DynamicField]] -> Text -> Html tableHead [[DynamicField]] rows Text tableName = [hsx| <thead> <tr> {forEach (columnNames rows) renderColumnHead} <th> <div class="d-flex"> <a href={NewRowAction tableName} class="btn btn-link btn-add" data-toggle="tooltip" data-placement="bottom" title={"Add " <> tableNameToModelName tableName} >{addIcon}</a> </div> </th> </tr> </thead> |] where columnNames :: [[a]] -> [b] columnNames [[a]] rows = forall a b. (a -> b) -> [a] -> [b] map (forall model (name :: Symbol) value. (KnownSymbol name, HasField name model value) => Proxy name -> model -> value get forall a. IsLabel "fieldName" a => a #fieldName) (forall a. a -> Maybe a -> a fromMaybe [] (forall a. [a] -> Maybe a head [[a]] rows)) renderColumnHead :: a -> Html renderColumnHead a name = [hsx|<th>{name}</th>|] renderRows :: [[DynamicField]] -> Html -> Text -> Html renderRows :: [[DynamicField]] -> Html -> Text -> Html renderRows [[DynamicField]] rows Html body Text tableName = [hsx| <table class="table table-sm table-hover data-rows-table"> {tableHead rows tableName} {body} </table> |] sqlValueToText :: Maybe ByteString -> Text sqlValueToText :: Maybe ByteString -> Text sqlValueToText (Just ByteString value) = forall a b. ConvertibleStrings a b => a -> b cs ByteString value sqlValueToText Maybe ByteString Nothing = Text "NULL" renderId :: a -> String renderId a id = forall a. Int -> [a] -> [a] take Int 4 (forall a b. ConvertibleStrings a b => a -> b cs a id) forall a. Semigroup a => a -> a -> a <> String ".." forall a. Semigroup a => a -> a -> a <> forall a. [a] -> [a] reverse (forall a. Int -> [a] -> [a] take Int 4 (forall a. [a] -> [a] reverse (forall a b. ConvertibleStrings a b => a -> b cs a id))) isBoolField :: a -> t model -> Bool isBoolField a fieldName t model tableCols = case (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a find (\model c -> forall model (name :: Symbol) value. (KnownSymbol name, HasField name model value) => Proxy name -> model -> value get forall a. IsLabel "columnName" a => a #columnName model c forall a. Eq a => a -> a -> Bool == (forall a b. ConvertibleStrings a b => a -> b cs a fieldName)) t model tableCols) of Just model columnDef -> (forall model (name :: Symbol) value. (KnownSymbol name, HasField name model value) => Proxy name -> model -> value get forall a. IsLabel "columnType" a => a #columnType model columnDef) forall a. Eq a => a -> a -> Bool == a "boolean" Maybe model Nothing -> Bool False isSqlFunction :: Text -> Bool isSqlFunction :: Text -> Bool isSqlFunction Text text = Text text forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `elem` [ Text "uuid_generate_v4()" , Text "NOW()" , Text "NULL"] isSqlFunction_ :: ByteString -> Bool isSqlFunction_ :: ByteString -> Bool isSqlFunction_ ByteString text = ByteString text forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `elem` [ ByteString "uuid_generate_v4()" , ByteString "NOW()" , ByteString "NULL"] fillField :: model -> a -> a -> a fillField model col a value a isBoolField = a "fillField('" forall a. Semigroup a => a -> a -> a <> forall model (name :: Symbol) value. (KnownSymbol name, HasField name model value) => Proxy name -> model -> value get forall a. IsLabel "columnName" a => a #columnName model col forall a. Semigroup a => a -> a -> a <> a "', '" forall a. Semigroup a => a -> a -> a <> a value forall a. Semigroup a => a -> a -> a <> a "'," forall a. Semigroup a => a -> a -> a <> a isBoolField forall a. Semigroup a => a -> a -> a <> a ");" getColDefaultValue :: ColumnDefinition -> Text getColDefaultValue :: ColumnDefinition -> Text getColDefaultValue ColumnDefinition { Maybe Text $sel:columnDefault:ColumnDefinition :: ColumnDefinition -> Maybe Text columnDefault :: Maybe Text columnDefault, Bool $sel:isNullable:ColumnDefinition :: ColumnDefinition -> Bool isNullable :: Bool isNullable } = case Maybe Text columnDefault of Just Text value -> Text value Maybe Text Nothing -> if Bool isNullable then Text "NULL" else Text "" renderRowValue :: Maybe ByteString -> Text renderRowValue :: Maybe ByteString -> Text renderRowValue (Just ByteString value) = Text "'" forall a. Semigroup a => a -> a -> a <> forall a b. ConvertibleStrings a b => a -> b cs ByteString value forall a. Semigroup a => a -> a -> a <> Text "'" renderRowValue Maybe ByteString Nothing = Text "NULL" renderDefaultWithoutType :: Text -> Text renderDefaultWithoutType :: Text -> Text renderDefaultWithoutType Text "" = Text "" renderDefaultWithoutType Text input = case forall (t :: * -> *) a. Foldable t => t a -> Int length (Text -> Text -> [Text] Text.splitOn Text "'" Text input) of Int 3 -> (Text -> Text -> [Text] Text.splitOn Text "'" Text input) forall a. [a] -> Int -> a !! Int 1 Int _ -> Text input isBooleanParam :: Bool -> ColumnDefinition -> Html isBooleanParam :: Bool -> ColumnDefinition -> Html isBooleanParam Bool isBool ColumnDefinition def = [hsx| <input type="hidden" name={get #columnName def <> "-isBoolean"} value={inputValue isBool} /> |] headerNav :: Html = [hsx| <div class="view-selector"> <div class="container-fluid"> <a href={ShowDatabaseAction} class={classes [("active", databaseActive)]}> Database </a> <a href={NewQueryAction} class={classes [("active", sqlActive)]}> SQL </a> </div> </div> |] where databaseActive :: Bool databaseActive :: Bool databaseActive = forall {k} (controller :: k). (?context::ControllerContext, Typeable controller) => Bool isActiveController @DataController Bool -> Bool -> Bool && Bool -> Bool not Bool sqlActive sqlActive :: Bool sqlActive :: Bool sqlActive = forall controller. (?context::ControllerContext, PathString controller) => controller -> Bool isActivePath DataController NewQueryAction Bool -> Bool -> Bool || forall controller. (?context::ControllerContext, PathString controller) => controller -> Bool isActivePath DataController QueryAction