I was worried that i was repeating the AddInputErrors function for each
form, because they were basically the same. I could create a Form type
and make all forms embed it, but i realized that with a separate
validator i would have cleaner validation functions and would not need
the Valid field in the form that i am using only for that method.
Similar to the profile form, the login form now parses and validates
itself, with the InputField structs that the templates expect.
I realized that i was doing more work than necessary when parsing fields
fro the profile form because i was repeating the operation and the field
name, so now it is a function of InputField.
This time i needed extra attributes for the login form. I am not sure
that the Go source code needs to know about HTML attributes, but it was
the easiest way to pass them to the template.
This is just to set the correct `lang` attribute on the HTML, so that
text readers can do its job and the `(optional)` suffix of labels gets
the correct ”translation”.
Let’s start first with a non-fancy validation method with just if
conditionals instead of bringing yet another complicated library. I
hope i do not regret it.
I wanted to move all the input field to a template because all that
gobbledygook with the .input div and repeating the label in the
placeholder was starting to annoy me. Now with error messages was even
more concerning.
I did not know whether the label should be a part of the input fields
or something that the template should do. At the end i decided that
it makes more sense to be part of the input field because in the error
messages i use that same label, thus the template does not have a say
in that, and, besides, it was just easier to write the template.
The same with the error messages: i’ve seen frameworks that have a map
with the field’s id/name to the error slice, but then it would be
a bit harder to write the template.
I added AddError functions instead of just using append inside the
validator function, and have a local variable for whether it all went
OK, because i was worried that i would leave out the `ok = false`
in some conditions.
I had started writing “constructors” functions for InputField and
SelectField, but then had to add other methods to change the required
field and who knows what else, and in the end it was easier to just
construct the field inline.
The symbols.svg files is for referencing from other SVG files with
xlink; the .glyph.json seems to be used for the search app; and the
.less file is useless to me because i do not use less.
I have been thinking about that, and it does not make that much sense to
have the titles in the Go source anymore: most of them are static text
that i have to remember to set in the controller each time, and when
the time come i have to face a dynamic title i am sure i will manage
with only the template capabilities—worst comes worst, i can always
define a function.
On the other hand, there is no way i can define a template without its
title and i know that everytime that template is used, no matter what
controller rendered it, it will always have that title.
For now i use CSS because we are not sure whether we will keep it this
way or not and, until we finally decide, with CSS is the easiest to
remove later on.
This is not necessary per se, but it makes my life easier because that
way i know which company the user was when she went to its profile and
can “return” back in the menu and future nav items.
At first we thought that a regular text field would do, because we were
afraid that a dropdown would be worse from the point of view of user
experience, but then we realized that we need the country code for VAT
and phone validation, and we can not expect users to input that, of
course.
I had to add the first “i18n table” to the database with the name of all
countries in both Catalan and Spanish and Catalan; English is the
default. For now i think i do not need a view that would select the
name based on the locale of the current request, because currently i do
not plan on adding any other such table —the currency uses the code and
the symbol, thus no need for localization.
However, now i need the language tag from the locale in order to get the
correct translation, and gotext does not give me any way to access the
inner language. Thus the need for our Locale type.
I do not have more time to update the update to the company today, but i
believe this is already a good amount of work for a commit.
The company is going to be used for row level security, as users will
only have access to the data from companies they are granted access, by
virtue of being in the company_user relation.
I did not know how add a row level security policy to the company_user
because i needed the to select on the same relation and this is not
allowed, because it would create an infinite loop.
Had to add the vat, pg_libphonenumber, and uri extensions in order to
validate VAT identification numbers, phone numbers, and URIs,
repectively. These libraries are not in Debian, but i created packages
for them all in https://dev.tandem.ws/tandem.
This function does not ask for the confirmation because this is an
user-facing issue, not for the database.
Still missing: validation and proper error messages.
This is for security, just in case two users have the same cookie,
althought it is unlikely, but nevertheless less guessable.
I also need to refresh the cookie when the user changes their email
address, because it is liked toghether. It does mean that it will
logout from everywhere else, but i can not do anything about that.
It works better than with the weird hover behaviour i could do in CSS,
and it already has most of the aria roles needed.
The only tricky part is to allow closing it by clicking anywhere else,
that is done by “extending” the <summary> to the whole screen, with a
lower z-index than the menu but higher than the rest of controls, that
way we force people to click on that summary.
I want this so that the Go application does not need to know the exact
details of the settings that the database sets when applying the cookie;
it just needs to select from the user_profile that already knows this.
Also, that way i can get the user’s language from its profile with a
single select, without having to check whether we are guest or
authenticated.
With that, i can skip the content negotiation if the user already told
us what language they want.