1
0
Fork 0
compareware/Web/Controller/Tasks.hs

126 lines
4.3 KiB
Haskell
Raw Normal View History

2023-04-16 10:33:20 +00:00
module Web.Controller.Tasks where
import Web.Controller.Prelude
import Web.View.Tasks.Index
import Web.View.Tasks.New
import Web.View.Tasks.Edit
import Web.View.Tasks.Show
instance Controller TasksController where
action TasksAction = do
tasks <- query @Task |> fetch
2023-04-16 13:54:20 +00:00
>>= collectionFetchRelated #tags
2023-04-16 10:33:20 +00:00
render IndexView { .. }
action NewTaskAction = do
2023-04-16 13:54:20 +00:00
let tags = [newRecord @Tag, newRecord @Tag]
let task = newRecord @Task
|> updateField @"tags" tags
2023-04-16 10:33:20 +00:00
render NewView { .. }
action ShowTaskAction { taskId } = do
task <- fetch taskId
render ShowView { .. }
action EditTaskAction { taskId } = do
task <- fetch taskId
2023-04-16 13:54:20 +00:00
>>= fetchRelated #tags
2023-04-16 10:33:20 +00:00
render EditView { .. }
action UpdateTaskAction { taskId } = do
task <- fetch taskId
2023-04-16 13:54:20 +00:00
let tagIds :: [Id Tag] = paramList "tags_id"
let tagNames :: [Text] = paramList "tags_name"
2024-04-06 15:47:37 +00:00
let tagValues :: [Text] = paramList "tags_value"
2023-04-16 13:54:20 +00:00
originalTags <- fetch tagIds
2024-04-06 15:47:37 +00:00
let tags = zip3 tagIds tagNames tagValues
|> map (\(id, name, value) -> originalTags
2023-04-16 13:54:20 +00:00
|> find (\tag -> tag.id == id)
|> fromMaybe (newRecord |> set #taskId task.id)
2024-04-06 15:47:37 +00:00
|> \tag -> buildTag tag name value
2023-04-16 13:54:20 +00:00
)
2023-04-16 10:33:20 +00:00
task
|> buildTask
2023-04-16 13:54:20 +00:00
|> updateField @"tags" tags
|> bubbleValidationResult #tags
2023-04-16 10:33:20 +00:00
|> ifValid \case
2023-04-16 13:54:20 +00:00
Left task -> do
render EditView { task }
2023-04-16 10:33:20 +00:00
Right task -> do
2023-04-16 13:54:20 +00:00
(task, tags) <- withTransaction do
task <- task
|> clearTags
|> updateRecord
tags <- mapM updateOrCreateRecord tags
pure (task, tags)
2023-04-16 10:33:20 +00:00
setSuccessMessage "Task updated"
redirectTo EditTaskAction { .. }
action CreateTaskAction = do
let task = newRecord @Task
2023-04-16 13:54:20 +00:00
let names :: [Text] = paramList "tags_name"
2024-04-06 15:47:37 +00:00
let values :: [Text] = paramList "tags_value"
let tags = zip names values |> map (\(name, value) -> buildTag newRecord name value)
2023-04-16 13:54:20 +00:00
2023-04-16 10:33:20 +00:00
task
|> buildTask
2023-04-16 13:54:20 +00:00
|> updateField @"tags" tags
|> bubbleValidationResult #tags
2023-04-16 10:33:20 +00:00
|> ifValid \case
2023-04-16 13:54:20 +00:00
Left task -> render NewView { task }
Right taskAndTags -> do
(task, tags) <- withTransaction do
task <- taskAndTags |> clearTags |> createRecord
tags <- taskAndTags.tags
|> map (set #taskId task.id)
|> createMany
pure (task, tags)
setSuccessMessage "Task and Tags created"
2023-04-16 10:33:20 +00:00
redirectTo TasksAction
action DeleteTaskAction { taskId } = do
task <- fetch taskId
deleteRecord task
setSuccessMessage "Task deleted"
redirectTo TasksAction
buildTask task = task
|> fill @'["description"]
2023-04-16 13:54:20 +00:00
|> validateField #description nonEmpty
2024-04-06 15:47:37 +00:00
buildTag :: Tag -> Text -> Text -> Tag
buildTag tag name value = tag
2023-04-16 13:54:20 +00:00
|> set #name name
2024-04-06 15:47:37 +00:00
|> set #value value
2023-04-16 13:54:20 +00:00
|> validateField #name nonEmpty
-- | Adds a validation error to the record when any of the child records is invalid
bubbleValidationResult :: forall fieldName record childRecord.
( HasField "meta" record MetaBag
, SetField "meta" record MetaBag
, KnownSymbol fieldName
, HasField fieldName record [childRecord]
, HasField "meta" childRecord MetaBag
, SetField "meta" childRecord MetaBag
) => Proxy fieldName -> record -> record
bubbleValidationResult field record =
if isEmpty childAnnotations
then record
else record |> attachFailure field "Invalid records"
where
childAnnotations :: [(Text, Violation)]
childAnnotations = get field record
|> map (\record -> record.meta.annotations)
|> concat
updateOrCreateRecord record | isNew record = createRecord record
updateOrCreateRecord record = updateRecord record
clearTags :: Include "tags" Task -> Task
2024-04-06 15:47:37 +00:00
clearTags task = updateField @"tags" (newRecord @Task).tags task