Skip to content
This repository has been archived by the owner on Nov 2, 2019. It is now read-only.

Create System for Overriding Display of Given Resource Types in Lists #71

Open
maxdumas opened this issue Apr 22, 2015 · 3 comments
Open

Comments

@maxdumas
Copy link
Member

Right now we just have a series of fallbacks hardcoded, currently going name || title || schoolName || id. This obviously isn't the most robust way to handle this, and its fails to account for types that require or desire more complex representation as strings.

A good example of this is Venue, for which we want to display the address as well as the name.

Another example is a TeamMembership. Currently all we show for that is its ID, as it doesn't really have any field that clearly maps to a string.

This is something that we should determine on the front end and not on the API side, as it will be application-specific.

@maxdumas
Copy link
Member Author

maxdumas commented May 6, 2015

So it looks like we're going to have a number of levels at which the solution to this is going to have to work. I'm going to call this solution the "format provider". We have two levels of data that we need to override formatting for, fields and resources. We also have two methods that we need to override them for.

Data

  1. Resources: Anywhere resource data needs to presented in a read-only fashion. e.g. listing elements of a resource in a dropdown/multi-select. The format provider in this case needs to afford translation of a given model for a given resource to a concise string that uses the element's data. See Add Bread Crumbs to Navbar #93, Show address for each venue's entry in the venues dropdown #45.
  2. Fields: This is where we define global behavior for the display of given types of fields, e.g. linked fields and date fields. See Linked resources do not appear in table in LIST action #86, Dates in List View should be in EST #99. Of course Linked resources do not appear in table in LIST action #86 would tie into resource display also, as ideally it would know to call the formatter for its linked resource to resolve itself, though we would need to be careful about the incurred cost of this as then we are fetching data for all dependent resources to list them. This could be mitigated by a good solution to Create API Data Cache Service #96.

Methods

  1. Custom templates: This is the most flexible solution in terms of display. For fields, like in Dates in List View should be in EST #99, Angular's date interpolation filter excels at this and is very flexible. For resources, we would have the flexibility to define a completely custom view for a given resource. A good use case for this might be something like TeamMembership, which is really unhelpful right now. Of course we'll need to be careful with these because of the loss of generality, but obviously there isn't a one-size fits all solution for displaying all of these resources. The definitions of these template getters would be something like format.getFieldTemplate(fieldType) and format.getResourceTemplate(resourceType).
  2. Custom formats: Templates have restrictions on where they can be used and consequentially may result in lots of redundant display code. Show address for each venue's entry in the venues dropdown #45 is a good example of this: We would have to redefine all of the dropdown code in every template for each resource the needs custom display logic. They also have a higher overhead than just normal interpolation, and obviously if we need the value somewhere outside of the DOM for some reason, then templates are useless. There are cases where all we may want is a concise string representation of a resource/field (especially a resource). The definitions of these "toString" methods would be something like format.field(fieldType, fieldValue) and format.resource(resourceType, resourceValue).

Does this make sense to you guys? Are there any other cases that you can think of?

@ethanresnick @grungerabbit @AbhiAgarwal

@ethanresnick
Copy link
Member

@maxdumas This sounds good. I mean, I doubt these will be the only types of extensibility we'll need down the line (e.g. eventually we're probably going to need many ways to configure the "add" view, from hiding or ordering fields to more dynamic things like #104). But we don't need to try to plan for all that stuff until we actually need it; we can always refactor later.

My big question, though, is about something we discussed earlier: whether we're building a tech@nyu-specific intranet or a framework on top of which anyone can build an angular+json-api intranet (with our intranet also being built on top of this framework). I think we should go for the latter, because the marginal costs are low while the benefits to the club's cred and the associated value to the contributors seems high.

I ask that question in this context—and it's something I want to talk more about tonight—because it'll have implications for your design above. For example, if someone calls format.getResourceTemplate(resourceType), how will that function know what template to return? In the world in which this is just a tech@nyu-specific app, we just hardcode a return value (some logic for picking a return value) that fits our needs. But in the world in which we're building a framework, we set up the format provider such that a user can configure it with templates/logic to use.

@maxdumas
Copy link
Member Author

Ethan and I discussed this farther and we're going to adapt the approach taken by his ethanresnick/json-api library. We're going to reorganize the customized logic from being services centered around functions for all resources to being services centered around resources for all their functions. In this system, for each resource that we want to define custom logic for, we would supply a custom service that would specify everything, with some other service providing sensible default values, either through lookup or through inheritance.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants