bleroy / Nwazet.Commerce

Idiomatic commerce module for Orchard CMS.
BSD 3-Clause "New" or "Revised" License
26 stars 21 forks source link

Territories? Regions? I don't like countries. #134

Closed MatteoPiovanelli-Laser closed 6 years ago

MatteoPiovanelli-Laser commented 6 years ago

Disclaimer: this post will be somewhat rambling.

I have been playing around some more and I was thinking about overhauling some stuff. Specifically, the way Countries and such are managed. (this applies both to taxation and shipping)

Currently, countries are just strings and that is a mess for localization.

I was thinking of having Territory objects representing this concept in a more fine grained way, and with ContentItems so that I can translate them while keeping the same concepts.

There would need to be a way to relate Territory objects in a many-to-many fashion as a sort of parent-child relationship:

e.g. Territory EU Contains 28 Territories (each one being a country). Territory UK is contained in EU (at least for a while longer) but at the same time is also a part of Territory Commonwealth, together with Canada and a bunch of other countries.

These territories would need flags to mark whether they are "valid" for shipping (for shipping purposes, Continental Italy is generally considered separate from Sicily and Sardinia) and whether they are a tax "unit" (same taxes, e.g. VAT, apply across all of Italy, including SIcily and Sardinia). THey may also need further flags, to specify whether they represent a Country, a State, a Province, a City.

THe current idea is: I would have a specific controller to handle defining territories and their relations. I would have a ContentType Territory (not listable, not creatable and so on, so it can only be handled form the TerritoryAdminController) representing the territories. I would have a TerritoryPart, with a string for the name of the territory. I would have a record TerritoryInternal that is not a ContentPartRecord and that is "unique" across localizations of a same Territory: the TerritoryPart of "United States" would be related to the same TerritoryInternal as the TerritoryPart of "Stati Uniti". Each TerritoryPart would have a reference to a TerritoryInternal record. I would also have arelationship table to maintain the n-to-n relationships between territories, that would have foreign keys to the TerritoryInternal table.

For Import/Export of the TerritoryInternal records they would probably need a string that identifies them uniquely.

Once that is in place, we can upgrade shipping and taxes to use those rather than work on strings, so that there is no need to micromanage the fact that I picked to get stuff shipped to "Italia" rather than "Italy" by creating duplicate shipping methods.

bleroy commented 6 years ago

That sounds terrific, like a CultureInfo for commerce. Would that be like a static repository of local knowledge in code, like CultureInfo is, or a more dynamic and database-bound thing? I'm assuming the latter, but initial setup could fill it with current data, I suppose.

MatteoPiovanelli-Laser commented 6 years ago

I am thinking dynamic, with some presets. Some presets could be in recipes, so that they may be different for a US store and a European one, for example. A list of countries could be loaded by default on feature setup.

MatteoPiovanelli-Laser commented 6 years ago

I will probably start working on this this week, maybe even today. Any input is appreciated.

The rough idea for the data right now:

public class TerritoryInternal {
    public virtual int Id { get; set; } //primary Key
    public virtual string GUID { get; set; } //I think we may need this to import/export
    public IEnumerable<TerritoryInternal> ParentTerritories; 
    public IEnumerable<TerritoryInternal> ChildrenTerritories;
}

e.g.: Territory: Italy ParentTerritories: EU, Europe, Schengen, EuroZone... ChildrenTerritories: the 20 regions of Italy.

I am still trying to figure out the best Orchard/NHibernate way to implement the n-to-n parent-child relationship between regions. Should I go as far as implementing my own ISessionConfigurationEvents for this? I am not an expert here, and I can't see a simple way to create the n-to-n to the same table using naming conventions.

The additional properties to a Territory are also giving me pause. I mean stuff like bool IsACountry, bool IsAShipmentTerritory, bool IsATaxTerritory. I don't feel these properties belong in the TerritoryInternal, or in the feature enabling management of Territories at all (except maybe IsACountry). The shipping features should "create" the IsAShipmentTerritory flag, set to true for territories that should "appear" when setting up or selecting shipments. Same deal with tax features and a IsATaxTerritory flag. In my head, TerritoryInternal currently has a Dictionary<string, bool> AdditionalProperties of flags, stored in a table with a foreign key to the TerritoryInternal it belongs to. The fact that values there are bool may be limiting, but I cannot think of a practical example where I would use something that is not a bool, except maybe to add currency information down the line. Another way would be to simply put the additional info in the ContentItem. That makes development much easier, but also makes the structure less robust unless we do something more: I could flag "Italy" as a country, but not "Italia" or "Italie". We would need some way to enforce synchronization of that info even beyond what we did for culture neutral parts and fields in Orchard, and that sort of goes against how Orchard works.

MatteoPiovanelli-Laser commented 6 years ago

Here a Gist with a quick sketch of the main classes. https://gist.github.com/MatteoPiovanelli-Laser/30eefad02d34b724e2cb66efd5b92d07 This does not consider the additional properties, or the migrations, and it's more pseudo-code than an actual implementation, tbh.

bleroy commented 6 years ago

As always, I dislike GUIDs and think they should be last resort. Territories already have a globally unique name. Literally.

bleroy commented 6 years ago

n to n relationships are always a pain. Let me ask this. Since this is fairly static information that we're going to read once per app lifetime, and rarely write, it seems like a full-blown relational model for it is way overkill. I'm wondering if we shouldn't make that a lot more lightweight by storing it somewhere as an XML document. The hierarchical nature of it makes it even more compelling IMO.

bleroy commented 6 years ago

A territory picker part makes sense, but so does probably a field. For the territories themselves, do they need to be content items?

MatteoPiovanelli-Laser commented 6 years ago

What follows is a long rambling post that partially gives my point of view on your comments, and partially expands on some ideas and goes off on several tangents.

I disagree that territories have a global unique name. Countries do, to an extent. Territories not necessarily. The same territory will have a different name depending on localization. Some territories may "exist" only in an ecommerce and not in another. An Italian ecommerce is not likely to need distinctions between US states, and a US ecommerce will probably not need to make a difference between continental Italy and its islands. And some ecommerce will be special cases. An actual example: A guy from my hometown has moved to Sardinia and sells typical Sardinian food. He does free delivery to my hometown, and my hometown alone. He would need to have a specific Territory especially for that.

On the other hand, I agree that GUIDs are ugly. I'd love to figure out a different way to identify a territory uniquely. One may argue that all its parent-child relationship may give a pretty accurate identification, but that honestly depends on the level of detail we get into when defining the Territories for an ecommerce instance: given European countries, and Schengen, EU, EuroZone as other territories, I think there's like 25 countries that would belong in (be children of) all three those Territories.

In the following I will write about "TerritoryPart", but it may work well as a TerritoryField. I would have the Territories be ContentItems, with an attached TerritoryPart. That part would have a reference to a "unique" (in the sense that this information should not, I think, be replicated anywhere in a tenant, e.g. in case of localization of the Territories) TerritoryInternal record, that is actually used in the n-to-n parent-child relationships. The TerritoryPart would also contain the string for the Name of the Territory, that can be localized. I would love for Territories as the back office user/admin sees them to have the flexibility of ContentItems, so that we may add stuff to them (like pictures). At the same time, the parent-child relationships should be kept separately and not messed with too much: they can be created/configured from back-office (with specific permissions), but I don't think they can be different across versions/localizations of a Territory. Also, using ContentItems would mean that I could, on principle, have a ContentType for the territories I use for shipping, and a different one for the territories that affect taxes. That may look like overkill, but maybe I want to use a specific ContentType with a TerritoryPart to describe where my products come from. So a great prosecco may come from Conegliano, and using parent-child territory relationships it would also turn up for searches of wines from the province of Treviso, the region of Veneto, or Italy. If I were to design a wine ecommerce, I may directly attach the TerritoryPart to the product.

As I am typing this, I am thinking that may be calling the string in the TerritoryPart "Name" is sort of limiting. A territory may be identified by a ZIP code. Let me come back to the example above of the guy in Sardinia: He may chose to extend free shipping to Canavese. This is a region in northern Italy that has no institutional definition, and include 133 towns, across 3 provinces. Then he would need to define the Territory "Canavese". But Canavese is not valid for an address. He would need to define those 133 towns as Territories, mark then as children of Canavese, and then the "free shipping" rule would be on Canavese. In the same fashion, rather than defining the towns, he may have defined the corresponding ZIP codes as Territories (maybe some towns are small enough that they share a ZIP code, I don't know).

I don't know about storing the relations in an XML. I probably would like a sort of cache, or anyway a data structure somewhere accessible and containing the relations, so that there is no need to rebuild several layers of parent-child relationships at every request. On the other hand, as a store gets bigger and more international this structure may become a pain to maintain, and possibly cumbersome. Thinking about the use of this, however, we may argue that we only really need to search this structure "upward", going from a territory through its parents until a stop condition is verified. I am thinking about shipping and taxes, and off the top of my head that would seem to be true. Also in the example of the wine shop above this could work: Suppose I want to search for all the wines from Veneto. I could, starting from Veneto, get all its children, at all depths, and look for those, or go through my wines, get their corresponding territory and search it parents for Veneto. The second case would be an upward search in the sense I discussed above. It would perhaps be better to have search in all directions, but I am saying that maybe, by choosing a way to have only one, we may be able to pay some performance and simplify things somewhere else. Maybe, limiting searches to a single direction may be a setting.

bleroy commented 6 years ago

Unique identifier: name of the territory in its own culture. Even if we didn't have that, you could also make the unique identifier specifiable by the editor and be done with it.

OK, so if you have compelling reasons to make those territories content items, there are many ways the relationships could be implemented without going through the pain of implementing your own n-n relationships. For instance, territories could be taxonomies, which would strangely make sense, and already has the notion of a hierarchy built-in. Or you could use item pickers.

MatteoPiovanelli-Laser commented 6 years ago

My issue with using pickers or taxonomies is mostly that the relationships they allow to build do not necessarily hold across localizations of a ContentItem.

Either solution would still require to build specific logic to handle the relationships, and I feel it would make more sense to directly have a separate thing. Off the top of my head:

MatteoPiovanelli-Laser commented 6 years ago

Regarding the fact that a terrotory's name in the local culture is a good unique identifier in itself, I don't agree. There are corner cases like this: https://en.wikipedia.org/wiki/Springfield_(toponym). In those cases, the name is not in itself enough. The ZIP code would probably work for those, but it may not work for everything, and some territories may not have one (there is a bunch of countries that do not use postal codes).

I am thinking if calling this thing we are analyzing a Territory is proper, or a misnonym.

bleroy commented 6 years ago

I don't understand why territories would need more than one parent. The localization issues you mention look like they could and should be fixed, both on taxonomies and content picker.

Do we really want to go down to the city level for this territory thing? Even if we did, disambiguation of the unique name would still be trivial.

Overall, I don't want to argue and counter-argue too long. It seems to me on the surface that you're overthinking it and not keeping it simple, but if you're confident that your scenarios require that level of complexity, who am I to contradict you? ;)

MatteoPiovanelli-Laser commented 6 years ago

There are several reasons why I think territories may need several parents. Mostly it has to do with the different "sets" one would have to deal when talking about international shipping and taxes. From Italy, for example, shipping to European countries, including Switzerland, often has the same rates, but for example Cyprus is different. However, considering the VAT that should be applied changes the grouping significantly, as for example Switzerland is not a member of the EU, while Cyprus is.

We could limit the groupings to "geographical" entities, and say Italy is in Europe, and the EU is not a Territory for this. Then we would have to go and define all shipping and taxes for each country (or select multiple countries there). I'd like it more if we had the territories already grouped, and then we would just have to define, e.g., a tax that applies to all EU countries. When the UK leaves, I would only change the EU Territory by removing a child, rather than change all taxes or shipping or other things where I had also picked the UK as a EU member.

Basically, I would pay in complexity by having the n-to-n parent-child relationships in the territories, to save back office users form having to handle groups in several places.

ContentPicker localization can be made to keep the selected contents in synch across localizations, That is what the CultureNeutral feature that is in Orchard's dev branch does. That may put enough of a constraint, perhaps.

Regarding going to city level, I would definitely say we want that. The example of the wine ecommerce is in itself compelling enough for me to do that. I would argue, actually, that on principle we should not have a limit on how "deep" we want to allow the territories to go. Examples of that:

bleroy commented 6 years ago

Oh, I see, it's not that you need multiple parents, it's that you need multiple hierarchies of territories depending on scenarios. This looks more and more like taxonomies to me.

Even if you need to go to the neighborhood level, disambiguation is trivial and best left to the site administrator. GUIDs are just too crappy and not justified in this case. Also, there's plenty of precedent in Orchard.

MatteoPiovanelli-Laser commented 6 years ago

If I treated this like hierarchies, I would end up having "duplicate" Territories, right? In the example form my last post, I would have a Cyprus for taxes and a Cyprus for shipment. Then I would have to match those, in the sense that once the User selects shipment-Cyprus for delivery, the taxes-Cyprus is selected "automatically". The reason I thought about multiple parents was to avoid that. Also, that way the system would be open to handle cases where those groups intersect: e.g. ShippingCompanyA does a group different than ShippingCompanyB, or there are specific tax treaties in place. I don't know enough about these kind of things to give concrete examples, to be honest.

Maybe we could have those hierarchies to terms, and those terms have a field (or something) where we select that that is Cyprus, so that the comparison/matching is done on that field. Is that what you mean?

bleroy commented 6 years ago

Yes, you would have duplicates. On the other hand, it seems like we're talking in the abstract a little too much here. I can't even picture what the UI to manage that would look like.

MatteoPiovanelli-Laser commented 6 years ago

Maybe, if I had a Territory, called Cyprus, somewhere, with no relationship to anything at all, then I could have a bunch of hierarchies (taxonomies? Maybe not exactly. Maybe something very similar.), whose elements have a TerritorySelector. Then even though I might have multiple elements selecting Cyprus, I'd be able to relate them through that. Upon localization/cloning, the reference would get duplicated, but not the Territory. These hierarchies then are all just trees. And they are the ones eventually specifying whether they are used for taxes, shipping, origin of wine bottles or whatever. And I could localize whole trees at a time.

I haven't started thinking about the UI yet, but I would say that something that looks like https://angular-ui-tree.github.io/angular-ui-tree/#/connected-trees could work as a starting point. Then:

bleroy commented 6 years ago

I like that quite a bit more, yes. Thanks for bearing with me...

MatteoPiovanelli-Laser commented 6 years ago

Thank you. I have a tendency to make things complicated for the sake of having a single thing do everything and a cup of espresso. I need people to walk me to simpler solutions, and a cup of espresso.

MatteoPiovanelli-Laser commented 6 years ago

Over the next few days I'll get back with something, and some code.

MatteoPiovanelli-Laser commented 6 years ago

I am working on this (see the Territories branch on https://github.com/LaserSrl/Nwazet.Commerce/tree/Territories). I am wondering: this feature will not depend on any other feature in Nwazet. Should we still keep it in this module? Would it make any sense to move it out? I am trying to think about use cases where we would use the territories, but nothing else out of Nwazet. I can think of a few, tbh, but then some Nwazet features would depend on an outside module (e.g., a shipping feature using the territory hierarchies), and that would maybe get messy to maintain.

Eventually, is there a way to update the repo so that rather than being the folder for the Nwazet.Commerce module, we are one folder up and have: /Nwazet.Commerce /Territories ?

MatteoPiovanelli-Laser commented 6 years ago

If you have time, could you maybe give a look at how I am setting things up in that branch? So far I've begun writing up the models and the permissions. Any comment is appreciated.

bleroy commented 6 years ago

I'd keep it in unless you have an actual other module (and not just a possibility) that needs it and that is unrelated to commerce. I don't understand what you're suggesting about going one folder up. Would that not effectively make it a separate module?

MatteoPiovanelli-Laser commented 6 years ago

Yes, it would. But it would keep it in the same repository.

Anyway, it's not going to be hard to cut everything related to territories out later on.

bleroy commented 6 years ago

Right, but unless I see a compelling scenario for separating them, I'd rather avoid the overhead.

MatteoPiovanelli-Laser commented 6 years ago

Sure.

MatteoPiovanelli-Laser commented 6 years ago

Quick update: This is proceeding a bit slowly because of several deadlines and emergencies.

I am building things step by step and adding tests along the way to avoid bad surprises near the end, because I feel this feature need to be really robust. To do that, I had to add a few references to the test project in the repo.

Any input you may wish to share on the little code I wrote is welcome.

MatteoPiovanelli-Laser commented 6 years ago

Design questions.

Let's say I have several ContentTypes that I use for TerritoryHierarchies. Items of each of these types have a TerritoryHierarchyPart. I also have several ContentTypes that I use for Territories. Items of each of these types have a TerritoryPart.

An item with a TerritoryHierarchyPart will "contain" a hierarchy of territories, as items with a TerritoryPart, like we discussed.

I am deciding if and how to limit the choice of types for territories in a hierarchy. There are several possibilities:

  1. I could use a setting for the definition of the TerritoryHierarchyPart for the type. 1.1. If no TerritoryType is set I could allow all TerritoryTypes 1.2. Or I could make this a required setting, that if it's not set explicitly creates a TerritoryType for the HierarchyType. 1.3. I could also allow several TerritoryTypes to be used under a single Hierarchy.
  2. I could use a value in the TerritoryHierarchyPart of each ContentItem. 2.1. If no TerritoryType is set I could allow all TerritoryTypes 2.2. I could make this a required setting, that if it's not set explicitly creates a TerritoryType for the HierarchyItem. 2.3. I could also allow several TerritoryTypes to be used under a single Hierarchy.
  3. Both 1. and 2. 3.1. The TypePartSetting would then be used as default, but each hierarchy would be able to override that.

In the scenarios where multiple TerritoryTypes are allowed for a hierarchy, clicking an "Add territory" button would present the user with a page to select the type, like it's done for contentItems.

Personally, I would set things up so that for a single HierarchyItem, it's only possible to have a single TerritoryType. I would have a setting on the typePartDefinition, used as default on the TerritoryHierarchyPart, where the user would need to actually make the choice. The Setting at the TypePartDefinition would be required, and default to creating a type. On the Editor for the TerritoryHierarchyPart I would not allow creating a TerritoryType, but I would (optionally, with a flag on the TypePartDefinition) allow choosing among a bunch of TerritoryTypes. The list of allowed types could be set on the TypePartDefinition: on the TerritoryHierarchyPart Editor the user would then be able to select from a subset of the types fomr the TypePartDefinition (because he may not be allowed to manage some of those types).

Basically, Having only the setting on the HierarchyType means: I have the TaxHierarchy type: each item of this type will have TaxTerritories. I also have the ShippingHierarchy type: each item of this type will have ShippingTerritories. While having the setting on the item means: I have the Hierarchy type: some items of this type will have TaxTerritories, and some will have ShippingTerritories.

Both scenarios can work, I think. However I would not have different TerritoryTypes in a single HierarchyItem, because that would quickly become messy when bringing stuff to the frontend.

I don't think I explained any point above very clearly, so please point out any inconsistency, or issues. Also, please let me know what do you think is the the best solution.

MatteoPiovanelli-Laser commented 6 years ago

I am going with having a setting on the TypePartDefinition that acts as default for the TerritoryHierarchyPart in ContentItems, and a flag that allows me to overwrite the dafult in each item (as long as there are not territories in the hierarchy).

bleroy commented 6 years ago

Sounds good. Sounds like "territory" should be a stereotype, no?

MatteoPiovanelli-Laser commented 6 years ago

I don't know enough about stereotypes to be able to give an opinion on that. What is your reasoning?

bleroy commented 6 years ago

Stereotypes are types of types, in a way. They are designed to identify commonalities between different types. A typical example is "widget". There are many types of widgets, but there's a need to recognize them (for the widget editor for instance). If you're going to have multiple different types that are all territories, it should probably be a stereotype.

MatteoPiovanelli-Laser commented 6 years ago

Wouldn't it be enough to recognize them as the types that have a TerritoryPart?

bleroy commented 6 years ago

That's a good point. If there's a useful part it must have then that works too.

MatteoPiovanelli-Laser commented 6 years ago

Yes there is one. I don't know if there is anything else attached to content types being in/of a stereotype. Maybe specialization of alternates/placement? For example, if I can say "alternate for content whose stereotype is territory" then it's worth it, because I can't say "alternate for content that has a TerritoryPart". Unless I specifically write code that allows me to do that. I guess I would have to write code to force that all items with a TerritoryPart have the stereotype for Territory and viceversa, but that shouldn't be too hard.

bleroy commented 6 years ago

You can add alternates for whatever you want. The stereotype is something that you have the responsibility for specifying when creating the type.

MatteoPiovanelli-Laser commented 6 years ago

Pasteing from questions I asked on Gitter:

question on tests for Orchard modules: I am basing my TestFixture class on DatabaseEnabledTestsBase. However, it looks like the 1-to-many relationships I have in my db for my records, and that I "establish" in my migration, are not there in the tests. Is this a limit in the base class implementation, that does not seem to be actually running the migrations? Or did I do something else that is wrong?

Matteo Piovanelli @MatteoPiovanelli-Laser 12:30 can't anyone point me in the right direction on setting my tests up for those relations to work?

Matteo Piovanelli @MatteoPiovanelli-Laser 12:54 Does sqlCe support the following: _contentManager.Query<MyPart, MyRecord>().Where(rec => re.Property == something)

Matteo Piovanelli @MatteoPiovanelli-Laser 15:07 and the message got deleted by mistake ... typing again I have my TestFixture class based on DatabaseEnabledTestsBase A test running calling a method with the above query fails with this info (translated roughly form Italian): Message: System.IO.FileLoadException: Impossible to load file or Assembly NHibernate, Version=3.3.1.4000, ... or one of its dependencies. The manifest definition for the specificed assembly does not match the reference assembly. (Exception form HRESULT: 0x80131040) StackTrace: DefaultCotnentQuery.Where(Expression<Func<TRecord, bool>> predicate, ICriteria bindCriteria) DefaultìContentQuery.Where(Expression<Func<TRecord, bool>> predicate) that version of NHibernate does not seem to be referenced anywhere in my code...

Matteo Piovanelli @MatteoPiovanelli-Laser 15:30 or in Orchard, even

Matteo Piovanelli @MatteoPiovanelli-Laser 15:37 Note that calling those same methods does not crash like that in the code where I am actually using them

Basically, I am trying to set up Unit tests for the 1-to-many relations between hierarchies and territories, but so far I have not been able to.

Development of the feature is still ongoing, whenever I can.

bleroy commented 6 years ago

Thanks for the update. I'm afraid I don't have any ideas on how to fix that, sorry.

MatteoPiovanelli-Laser commented 6 years ago

Fixed the issue by adding an App.config telling the test project to load the specific version of nhibernate.dll Still not have the 1-to-n relations in the test fixtures, so i'll have to look more on that

MatteoPiovanelli-Laser commented 6 years ago

Hi,

update:

The CRUD is all in place for this feature. I still have to:

MatteoPiovanelli-Laser commented 6 years ago

CRUD and related services are ok, except for where the methods use the 1-to-many relationships: in the test fixture those are not filled up, for some reason.

I'd rather not do a PR yet, because the other points are still todo, but if you have the time maybe you could review the code already? It's on https://github.com/bleroy/Nwazet.Commerce/compare/master...LaserSrl:Territories (Note: that branch i linked should not be pulled, because it references the Orchard solution from a different folder rather than using project references)

Moving on:

import/export: I would have a "Territories" entry in Admin/ImportExport/Export, rather than have the stuff in the "Content and Content Definition" section. Exporting specific hierarchies will mean also exporting all the Territories in them, as well as the unique records we defined that identify those.

Localization: Localizable hierarchy should mean localizable territories. Also, it should be impossible to hit "new translation" on a territory if the hierarchy does not have a different localiaztion that does not have the translation for that territory. Moreover, hitting "new translation" on the hierarchy should create all the localized contentitems for the territories (actually, saving the localization should do that). I wish the localization stuff from the dev branch were already in the 1.10.x branch, so I'd be able to use cloning for this. Either way, I'll do import/export first.

Matching service: This will be needed for stuff like matching tax conditions and shipping information. I'll get back to you on this.

MatteoPiovanelli-Laser commented 6 years ago

State: Veryfing import/export tracking a weird thing that causes the editor for a territory, upon hitting save, to return an HttpNotFound and leave the item as draft. Creating a base recipe that imports all the countries (using the list from Countries.cs, because finding a consistent list of countries in the world is surprisingly hard) and creates a hierarchy of territories called World

MatteoPiovanelli-Laser commented 6 years ago

feature is mostly done, so a PR is incoming (probably today), that contains:

This has been tested on my dev machine using MS-sql.

I'll add a further feature to handle localization of this stuff, but that may end up in a later PR.

MatteoPiovanelli-Laser commented 6 years ago

A note: the UI of the thing in the PR is bad. For the hierarchies, I recycled the UI that is currently used for Menus. Load the hierarchy from the recipe included in the PR, and you immediately see that does not "scale" well to these many items. On the other hand, I'd rather finish the whole functionality than reskin the UI there.

MatteoPiovanelli-Laser commented 6 years ago

I opened separate issues for the further additions to this feature, so I'll go ahead and close this issue