ihp-ide-1.5.0: IHP/IDE/SchemaDesigner/View/Policies/New.hs
module IHP.IDE.SchemaDesigner.View.Policies.New (NewPolicyView (..), policyFormModal) where
import IHP.ViewPrelude
import IHP.Postgres.Types
import qualified IHP.Postgres.Compiler as Compiler
import IHP.IDE.ToolServer.Types
import IHP.IDE.SchemaDesigner.View.Layout
data NewPolicyView = NewPolicyView
{ statements :: [Statement]
, tableName :: Text
, columns :: [Column]
, policy :: Statement
}
instance View NewPolicyView where
html NewPolicyView { .. } = [hsx|
<div class="row g-0 bg-white" id="schema-designer-viewer">
{renderObjectSelector (zip [0..] statements) (Just tableName)}
{renderColumnSelector tableName (zip [0..] columns) statements}
</div>
{migrationStatus}
{renderModal modal}
|]
where
modal = policyFormModal tableName columns policy (pathTo CreatePolicyAction) mempty "Create Policy" "New Policy"
-- | Shared form modal for creating and editing policies.
policyFormModal :: (?context :: ControllerContext, ?request :: Request) => Text -> [Column] -> Statement -> Text -> Html -> Text -> Text -> Modal
policyFormModal tableName columns policy formAction extraHiddenFields buttonText modalTitle = Modal { modalContent, modalFooter, modalCloseUrl, modalTitle }
where
modalContent = [hsx|
<form method="POST" action={formAction} class="edit-policy">
<input type="hidden" name="tableName" value={tableName}/>
{extraHiddenFields}
<!-- These will be filled via JS from the ace editors -->
<input type="hidden" name="using" value={using}/>
<input type="hidden" name="check" value={check}/>
<div class="mb-3">
<input
id="nameInput"
name="policyName"
type="text"
class="form-control"
autofocus="autofocus"
value={policy.name}
/>
</div>
<div class="mb-3">
<label for="using">Visible if:</label>
<textarea
id="using"
name="using"
type="text"
class="form-control sql-expression"
data-autocomplete-suggestions={autocompleteSuggestions}
>{using}</textarea>
<small class="form-text">This SQL expression needs to return True if the row should be visible to the current user. This is the <code>USING</code> condition of the Postgres Policy</small>
</div>
<div class="mb-3">
<label for="using">Additionally, allow INSERT and UPDATE only if:</label>
<textarea
id="check"
name="check"
type="text"
class="form-control sql-expression"
data-autocomplete-suggestions={autocompleteSuggestions}
>{check}</textarea>
<small class="form-text">Use this to e.g. disallow users changing the user_id to another user's id. This is the <code>CHECK</code> condition of the Postgres Policy</small>
</div>
<div class="text-end">
<button type="submit" class="btn btn-primary">{buttonText}</button>
</div>
</form>
|]
modalFooter = mempty
modalCloseUrl = pathTo ShowTableAction { tableName }
using = policy.using
|> maybe "" Compiler.compileExpression
check = policy.check
|> maybe "" Compiler.compileExpression
autocompleteSuggestions =
columns
|> map (.name)
|> intercalate ","