v0.12.0 (Beta 10.07.2021)
A new IHP release with new features and bug fixes. Over 100 commits have been merged since the last release 馃殌
Major Changes
-
Pagination:
IHP has a new built-in pagination module.Given an action like this:
action PostsAction = do posts <- query @Post |> orderBy #createdAt |> fetch render IndexView { .. }
We can paginate our results by adding a call to
paginate
:action PostsAction = do (postsQuery, pagination) <- query @Post |> orderBy #createdAt |> paginate posts <- postsQuery |> fetch render IndexView { .. }
We also need to change the view:
module Web.View.Posts.Index where import Web.View.Prelude data IndexView = IndexView { posts :: [Post] , pagination :: Pagination -- <---- Pass pagination variable to the view } instance View IndexView where html IndexView { .. } = [hsx| <div> {forEach posts renderPost} </div> {renderPagination pagination} -- <---- CALL renderPagination |]
Here's how the pagination looks like in the view:
When you're adding a new Controller to your app, you can use the new pagination checkbox to automatically generate the needed code:
-
Job Timeouts:
You can now configure a timeout for Job Workers:instance Job EmailCustomersJob where perform EmailCustomersJob { .. } = do customers <- query @Customer |> fetch forEach customers sendToCustomer where sendToCustomer customer = sendMail (MarketingMail customer) timeoutInMicroseconds = Just $ 1000000 * 60 -- 60 seconds
-
Added function to delete files from the cloud storage
You can now useremoveFileFromStorage
to remove uploaded files from S3 or any other configured cloud storage:action DeleteUploadedFileAction { uploadedFileId } = do uploadedFile <- fetch uploadedFile let storedFile = StoredFile { path = get #objectPath uploadedFile , url = get #url uploadedFile } removeFileFromStorage storedFile deleteRecord uploadedFile redirectTo UploadedFilesAction
-
Custom CORS policies
If you're building APIs with IHP you can now specify a custom CORS policy:-- Config.hs import qualified Network.Wai.Middleware.Cors as Cors config :: ConfigBuilder config = do option Development option (AppHostname "localhost") -- The boolean True specifies if credentials are allowed for the request. You still need to set withCredentials on your XmlHttpRequest option Cors.simpleCorsResourcePolicy { Cors.corsOrigins = Just (["localhost"], True) }
-
New Helper Function:
allEnumValues
Given a enum defined in theSchema.sql
like this:CREATE TYPE colors AS ENUM ('yellow', 'red', 'blue');
you can call
allEnumValues
to get a list of all the colors:let allColors = allEnumValues @Color -- allColors = [ Yellow, Red, Blue ]
This also works if you define custom type in
Web/Types.hs
that is derivingEnum
:data Color = Yellow | Red | Blue deriving (Enum) let allColors = allEnumValues @Color -- allColors = [ Yellow, Red, Blue ]
-
Respond with XML in your action:
We added a
renderXml
function:action MyVeryEnterprisyAction = do renderXml "<xml></xml>"
-
Added support for Unique Indices
You can now use
CREATE UNIQUE INDEX
statements inside yourSchema.sql
:CREATE UNIQUE INDEX users_index ON users (user_name);
Other Changes
- Fixed a crash in the Storage module
- Turned default.nix into a function by adding a param "pkgs" that defaults to . If nothing is passed in this should behave as ushall, but now the file can be imported using the nix builtin "import".
- Build .envrc already during ihp-new instead of on first project start
- IDE -> Data Editor: keep query in ace editor after submitting
- IDE -> Data Editor: Show sql errors in the same page instead of showing crash page
- Server-side Components: Fixed text fields and textareas not updating
- Updated jquery to 3.6.0
- Make sure that WebSocket.onClose is always called
- Added missing intances for TimeOfDay
- Support TSVector fields inside the database
- Form JS helpers: Use query parameters to transmit form values where the form is submitted via GET
- Fixed filterWhereIn and filterWhereNotIn not using IS NOT NULL when checking for null-ness of a field.
- Fixed imagemagick transforms not working as expected
- Prefix enum data constructors that would cause a compile-time error because of non-distinct naming with the type name
- Lot's of improvements to the documentation
- Use O1 by default for compiling Scripts in production, similiar how we do it with the background job worker
- Updated social links in the dev tools
- New documentation on joins
Updating
See the UPGRADE.md for upgrade instructions.
If you have any problems with updating, let us know on the IHP forum.
馃摟 To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter.