I should be able to change the Type of a Property
Summary: Only where it makes sense, but we should at least be able to change a Text Property to a Large Text, and vice versa. In the longer run, we should have as robust a Type-conversion system as we can manage.
Note that this existed once upon a time, so this is technically a regression and the back end code to support it existed in Space
and PropTypeMigrator
until Sept 2016, but the UI never made it into the SPA client. Since PropTypeMigrator was fairly ghastly code anyway, and nobody actually asked for this feature during the 18 months in which it wasn't available, I've decided to simply scrap the whole thing and start again from scratch.
First Pass
This is an Epic, and probably will want to get broken out before implementation. To begin with, we'll need the following elements:
- We'll need a UI to choose the Type to convert to, probably as a new button and dialog in Advanced Edit Property. This should restrict itself to the Types that are legal, based on
canCoerceTo
.
- The UI should forbid changing the Type of a Property in an App, at least for now. That's a bit sad, but it is highly likely to break copies of the App.
- In
modifyThing
, we should check the current and target Types using canCoerceTo
, and reject the request if it doesn't pass.
modifyPure
, if this is a Property and we're changing its Type, we need to look up all instances of this Property in the Space, and run them all through coerceTo
.
Imprecise Conversions
Sometime later (this should become at least one separate, lower-priority story), we should add the ability to do imprecise conversions. This means introducing concepts of "widening" and "narrowing" the Type (although we should come up with better terminology). For example, any Whole Number can be widened to a Text; you can try to narrow a Text to a Whole Number (that is, parse the fields), but it may not work. Ditto for TrueOrFalse, and so on. It should also be true for the numeric Types -- you can widen a Whole Number to a Float, or narrow a Float to a Whole Number.
The tasks are roughly:
- Introduce the concepts of "widen to" and "narrow to" in the back end, parallel to
coerceTo
. Again, this will need two methods each. Possibly we should enhance canCoerceTo
, instead of just returning a Boolean, to return an enum describing how it would convert. (Do we actually care about having widen separate? In principle, widen
should always succeed -- it just converts to a Type that may not reliably convert back.)
- In the actual implementation of
narrowTo
, return the new value and an indicator of whether information was lost.
- In the UI, allow the user to choose one of these widenings / narrowings in Change Type.
- If the user chooses a narrowing, immediately run
narrowTo
on all values in the Space. If any of them say that information was lost, pop a warning that not all values will convert safely. Maybe list all the Things for which this is true.
- If they choose to convert anyway, do it.