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.