Come up with domain specific state shape that works best for the app, and not necessarily derived from API syntax.
The current syntax is derived from the App Search API syntax. It is highly nested and difficult to work with, especially when try to add or remove filters. This is because the API syntax is geared towards providing a DSL for querying, it was not designing with the intention of state management.
For this reason, a new state shape for managing UI state is would be better.
This will also push the connectors in a slightly different direction. Rather than converting to/from the App Search API syntax, they'll be converting to / from Search UI state syntax.
Design
Note: Not modeling value types
- Date, Text, Geo, Number
The App Search API does not distinguish between the Geo, Date, Text, and Number types. So likewise, the UI does not distinguish, because there is no way to tell what the schema is by looking at values in an API response. We just pass values through and let the API figure out what is what. This means that no code in Search UI can automatically detect a value as being a Date, for instance and format it or treat it as a date explicitly. Components will need to have optional flags that tell a component that they're dealing with Dates if they need to render values as dates, etc.
This is an overall positive approach I believe, because it's entirely possible that different backends will have different value types. For instance, we don't support a Boolean type, but other APIs may. This way, we just pass the value through and don't worry about the particular type, so it should "just work"
Filter
- field: String - Which field is this filter associated with
- type: FilterType - "all", "or", "none"
- values: [FilterValue] - An array represents "or" filters
Facet
- field: String - Which field is this facet associated with
- type: String - "range" or "value"
- data:** [FacetValue]
FacetValue
- count: Number
- value: FilterValue
FilterType: String["all" | "none" | "or"]
** FieldValue: <String, Boolean, Number> **
FilterValue > FilterValueRange<T:FieldValue>
- to: <T>
- from: <T>
- name: String - We'll need this to correlate applied dynamic Date Range filters with options in corresponding range Facets on a page reload. This will not be an optional field.
FilterValue > FilterValueValue: FieldValue
Cases to consider:
- Detecting if any filter value is applied to a particular field
- Not applying the same filter twice / uniqueness
- Switching between "all" and "or" for a field
- Deleting all filters values for a field
- Deleting an individual filter field
- Adding a new filter
- Creating specific types of filters via components, like a RangeFilter component with "from" and "to" fields.
- Facet filters