Features
Improvements to the handling of dates and times
The storage for dates and times with respects to timezones has been improved in this version of C#Bot with a more standardised paradigm for how things work on the client and serverside. Prior to version 3.0.0.0, no timezone information was ever stored in the database, with the application needing to identify how to interpret the information. With changes to Entity Framework Core 6, the date times in the database are now stored as UTC timestamps instead. This is excellent for many scenarios, however can cause issues if the date time that is being stored is related to a local time and not to UTC.
To resolve this there has been several changes made to C#Bot to facilitate better practices when using date times.
- The
DateTime
attribute will now store all values in UTC time by default.- There is an option on
DateTime
to prevent the date time from being stored in the database. - As a general rule, UTC timestamps are good for storing data for an instant in the past, where date times without timezones are good for storing times that are in the future at a specific location.
- There is an option on
- The
Date
andTime
attributes will now no longer store dates its values asDateTime
with the irrelevant component ignored, but instead use the new .NET 6DateOnly
andTimeOnly
types.- This allows for easier comparisons and queries of date and time values.
- Date times with timezones are now stored as local timezones on the clientside and are converted to UTC timestamps when sent to the server.
- For example, for a user in the
Australia/Brisbane
timezone, the date object on the clientside will have a timezone offset of+10:00
. When the date time is serialised to be sent to the serverside it will be in the format of2022-01-01T15:00:00+10:00
. When this is deserialised by the server, it will be automatically converted to a UTC timezone.
- For example, for a user in the
- Date times without timezones will be stored as a Date object on the clientside with the timezone component ignored. When serialised to be sent to the server, the will using the the format of
2022-01-01T15:00:00
.
For more reading on date times, please read Storing UTC is not a silver bullet.
CSV Output Customisation
Addded ability to use custom CSV class maps and type converters for bot written CSV endpoints (the export endpoint on entity controllers).
- A class map can be used to change the output of a class in the CSV.
- A type converter can be used to change how a type is serialised and deserialised to a string for use in a CSV.
- Examples of how to use these features can be found here.
In addition a new ICsvWriterFactory
service has been added that can be used to create CsvWriter
classes with the global configuration already applied.
Improvements
- Configured ESLint to ignore whitespace issues inside of comments.
- Added
between
comparison type for where expressions in graphql. This can be used to find values between 2 scalar values in the database.- This can be used to find any date times between 2 supplied date times.
- This can also be used to find any number between 2 supplied numbers.
- There is an example of a between question in the migration notes for date time API changes.
- Added overload to the
TimeBufferedSection
constructor to acceptTimeSpan
. Updated internal handling of the class to perform less unit conversions. - When a CrudService transaction is rolled back, any files that were created will be cleaned up as well.
- This is done in a background job to not hold up the main endpoint logic any more than needed.
- Added ability to change the data type of decimal attributes.
- The default data type is
double
which will store the data as a double precision floating point number. This is the same behaviour as prior versions. - There is now an ability to set the data type as
decimal
. This value is a fixed range floating point number that will not have suffer from precision loss. This data type is appropriate for financial calculations.
- The default data type is
- Updated the types for the
js-cookie
package to the latest version. - Removed the
PasswordInput
component and merged its functionality with thePassword
component. - Added a
clickToClear
prop to the date time picker that will show a clear button on the input when enabled. - Added ability to configure cookie lifetime from appsettings.
- The appsettings field to use is
CookieConfiguration__CookieLifetime
and the format is defined by the"c"
format specifier for C# TimeSpans.
- The appsettings field to use is
- Added ability to
useAsync
to suppress the loading state after the initial load. - Pass
AbortSignal
to methods called byuseAsync
so they can be aborted in the case the hook is unmounted. - Added ability to combobox to disable and add descriptions to options.
- Added ability to use
ReactNode
instances as labels for all inputs. - Added ability to configure the serialisation logic for client side entities.
Resolved Defects
- Fixed an issue where an incompatible version of
react-error-overlay
was creating an invisible iframe that would prevent interaction with the screen. - Fixed an issue where accounts were not being deactivated corrected when calling the deactivate endpoint.
- Fixed an issue where order by parameters on nested graphql queries would fail if there was more than one condition specified.
- Fixed an issue where bulk deletes from the admin crud interface would not work if one of the filter conditions contained an enum.
- Fixed an issue where the
RemoveField
method onComplexGraphType
did not work. - Fixed an issue where the
FieldsToUpdate
parameter for GraphQL and CrudService updates did not work for user entities. - Fixed an issue where the range validator could cause certain tests to fail when placed on a decimal attribute.
- Fixed an issue where the password reveal icon would display twice on Microsoft Edge.
- Fixed an issue where certain tests would fail if there was a timeline entity on a user entity.
- Fixed an issue where string length validators were being ignored in certain tests.
- Fixed an issue where subqueries were not working in has conditions.
- Fixed an issue where not all bot written serverside tests were flagged with the
BotWritten
trait category.
Migration Path
Date time API changes
When saving or querying, the data that is passed to the server must have a timezone if the field has the timezone enabled, or not have a timezone if the timezone disabled.
For example in the following query created
is a field that has a timezone, where timeAndDateOfReportPublication
is stored without a timezone. In the variables for the query, the values for created
will also have a timezone, where the values used for timeAndDateOfReportPublication
do not have any timezone information. If this was not the case, then the API would throw an error warning the user that the format is wrong.
Query
query testQuery($createdRange: [String], $reportRange: [String]) {
reportEntitys(conditions: [
[{path: "created", comparison: between, value: $createdRange}],
[{path: "timeAndDateOfReportPublication", comparison: between, value: $reportRange}]
]) {
created
timeAndDateOfReportPublication
}
}
Variables
{
"createdRange": ["2022-07-01T00:00:00+10:00", "2022-07-30T00:00:00Z"],
"reportRange": ["2022-07-01T00:00:00", "2022-07-30T00:00:00"]
}
PasswordInput Removed
With this version the PasswordInput
component was removed. Please update any reference to it to use the Password
component instead.
Known Issues
Failing Date Time Selenium Tests
In cases where there are entities with multiple date time attributes on them, botwritten Selenium tests for update and create can fail with a StaleElementReferenceException
.