PRX / dovetail-insights

GNU Affero General Public License v3.0
0 stars 0 forks source link

UI Considerations #1

Open farski opened 3 days ago

farski commented 3 days ago

Lens Select

The Data Explorer always operates as some specific lens. The purpose of lenses, and the way the Explorer operates for any given lens, tend to be fairly similar, but there are important differences. There are differences both in what inputs are required from the user to generate results, and how those results are displayed.

For example, one lens may be able to generate results as both a table and a chart, while some other lens may never be able to display results as a chart. One lens may require that the user select a period like "daily" or "monthly", and another lens may have no concept of periods like that.

From a user standpoint, selecting the lens is probably the first thing that should happen. We should decide if it's possible for the lens selection to change after that.

The UI should anticipate between 4 and 6 lens types to start, but that could change over time and the UI should accomodate growth.

The UI does not need to be able to specifically handle cases where someone has changed the lens type in the URL after constructing a query. It should validate the inputs for the new lens as it normally would.

Time Range Input

The Data Explorer always requires a time range to generate results. The user defines a time range by selecting a start and end values. These values can either be absolute values or relative values. The backend allows a range to mix absolute and relative values.

When setting relative values, the backend expects values that take the form of an expression like now, now/Y, now-1/Y or now-2/M+15D+12h. These expressions can get a bit long and complicated, but their usefulness comes from their flexibility, so users should be able to enter them and tweak them directly in some way, even if that's not the default way they are surfaced in the UI. When a user is inputting relative value expressions, there should be some affordance to let them check that the expression is doing what they want (i.e., somehow show the date and time that the expression resolves to, or describe the expression in words.).

When setting absolute values, the backend expects values that take the form 2024-06-19T12:34:56Z and represent an instant in time, without any partial seconds. The backend will also automatically interpret 2024-06-19 as 2024-06-19T00:00:00Z. The backend always and only uses UTC.

The UI for inputting absolute values could allow the user to ignore hours/minutes/seconds if they are not needed, or we omit hours/minutes/seconds entirely, and start by only offering date inputs. The UI could allow the user to select values in a time zone other than UTC, but those values would need to be correctly converted prior to being passed to the backend.

The UI should be able to handle values that aren't necessarily possible to select with the UI. For example, the UI may not directly offer mixing absolute and relative values, but someone could change the URL to create that situation, and since it's supported by the backend, it should be supported by the UI as well.

The backend always treats the passed start value as inclusive, and the passed end value as exclusive. There's no requirement for the UI to appear to work that way. For example, we may want the user to be able to select start=June 1, end=June 30 to select the entire month of June (rather than start=June 1, and end=July 1). As long as the June 30th user input is correctly transposed to 2024-07-01T00:00:00Z before it's passed to the backend, that's fine. (Same thing for when the page loads after the end value has already been set, it would need to know to transpose 2024-07-01T00:00:00Z to June 30 in the UI.) If/when the end values include a time component, this sort of transposition doesn't really make any sense.

The UI should offer some standard, common ranges that the user can select to fill in the start and end values (things like: Previous 7 days, Previous week, Previous month, This year, etc). It should be clear to the user if the values being filled in are absolute or relative.

Filters

All lenses support filters, and all lenses support the same possible filters and in the same way(s). The UI for filters probably should not change based on lens selection.

Filters are based on dimensions of the data (things like user agent, country, etc.). Any given dimension can have at most one filter (meaning, at no point could two user agent filters be added).

Filters are optional, and the user should not have to select any filters to successfully query some data. (Worth noting that, internally, the backend will almost always do some filtering, based on the user's authorization and permissions, such as which podcasts they have access to, even if the user does not add a filter based on the podcast dimension).

All filters operate as either include or exclude.

The nature of dimension determine the way or ways in which the filter for that dimension function, and what inputs are needed from the user.

For example, a dimension like podcast may have a filter that allows the user to select which podcasts to include (or exclude) in the resulting data. This filter represents a list of one or more podcasts. Something like defining a range wouldn't make sense for the podcast dimension. Conversely, a dimension like publish date may have a filter that allows the user to include (or exclude) data for only a set of episodes published during a certain window. In this case, it does make sense for the filter to allow the user to select a range.

The UI for filters should allow for this variability, without becoming overwhelming.

The UI should anticipate at least 20 dimensions being available for filtering, but that number will grow over time.

A user may add no filters, or will likely often add between 1 and 3 filters, or may rarely add many filters. The UI shouldn't dedicate unnecessary space for filters, but should cleanly accomodate cases where many filters have been added.

The user should be able to disable a filter, without removing it and its configuration entirely.

A filter may be able to operate in multiple modes. For example, a filter for the publish date dimension, in addition to a range input, may also allow the user to include only episodes that were publised on a particular day (or days) of the week, like only Saturday and Sunday. Other filters, like the podcast filter, may only operate in one mode.

Or… a podcast filter may only operate in one "select" mode today, but later we may add an additional mode for that dimension. Something like starts with, where the user can include podcasts whose names start with a particular string.

The point is that we should create a UI that allows us to introduce new filter functionality without much friction over time.

At this stage of development, the focus should be on creating a UI that nicely handles:

All the various UIs for different modes of different dimension types are not being defined at this time – the system being design should be able to handle a wide variety of what those UIs may end up looking like, and not break down as additiong filter mode UIs are added over time.

In general, though, the filter UIs will need to support things like:

A user may select a value in a filter, such as a podcast in the podcast filter, and when they revisit the page (such as if they bookmarked it), they may no longer have access to that podcast (because their authorization or permissions changed). The backend will validate these situations, but if the UI can catch those things earlier (like if the UI loads the list of available podcasts and sees that the selected one is not included), that could be helpful.

brandonhundt commented 3 days ago

Thanks for this @farski. I appreciate you outlining your thoughts here, so we can reference them in the design phase. Also, I think we have a lot of existing elements in our shared styles that we can leverage to design this UI to ensure it remains intuitive.