Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: UI configuration #359

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

Proposal: UI configuration #359

wants to merge 2 commits into from

Conversation

pkalita-lbl
Copy link
Collaborator

This is just a starting point of a discussion and not necessarily fully thought-out yet.

The basic idea is that a schema (LinkML or otherwise) generally can't capture everything about how a tool to collect data adhering to that schema should look or behave. Obviously the schema can inform some sensible defaults (i.e. provide a dropdown menu when a value must be chosen from an enumeration) but it can't capture things like "suggest terms retrieved from this arbitrary endpoint". Or "this field should be omitted from the entry UI because it will be populated by a separate process" (see #337). For use cases like these that are common enough, it would be nice for data-harmonizer clients to not have to write a lot of custom code and instead simply provide some configuration.

The changes here represent a very basic sketch of what a UI configuration approach might look like. A data-harmonizer application (i.e. web/index.js) provides a UI configuration object to the DataHarmonizer constructor (an application could even store this configuration in a standalone JSON file). The DataHarmonizer class is responsible for interpreting this configuration and applying the correct settings internally. The specific example implemented here is directing the DataHarmonizer instance to use an OLS-based autocomplete for a particular field.

It's not implemented in this proof-of-concept, but you could also imagine a UI config like:

{
  "fields": {
    "internal_id": {
      "hidden": true
    },
    "look_but_dont_touch": {
      "readonly": true
    }
  }
}

I could also imagine non-field-specific configuration going outside of the "fields" key (e.g. #334):

{
  "numFrozenColumns": 2
  "fields": {
    ...
  }
}

Again, this is just a conversation starter. I'd be interested to know if this might address (or not) other cases.

cc: @ddooley

@pkalita-lbl pkalita-lbl changed the title Proposal: Proposal: UI configuration Sep 28, 2022
@pkalita-lbl
Copy link
Collaborator Author

Tangentially related: the idea of a separate UI configuration is not uncommon in the world of libraries that generate forms from JSONSchema. For example: here and here.

@ddooley
Copy link
Collaborator

ddooley commented Feb 11, 2023

Hi Patrick, sorry for delay in looking at this closely - I'm realizing discussion was held up. I totally see need to add DH interface configuration such as number of columns to freeze, but it seems like there are two types of configuration - ones that don't depend on a specific schema/class at hand, and those that do, i.e. with some classes it makes sense to freeze 2 panes, or hide x columns.

I was wondering for configuration how much mileage we could get out of encoding user interface behaviour right into a class or slot annotation, such that it could apply to any tool that displays it, if desired? Or name that tool explicitly in the annotation, e.g.

class_X: {
  annotations: {
    ui_behaviour: {
       DataHarmonizer: { // Optional layer ???
         numFrozenColumns": 2
       }
    }
  ...
   slots: {
     "internal_id": {
       "annotations": {
          ui_behaviour: {
             DataHarmonizer: { // Optional layer ???
                "hidden": true,
                "readonly": true  // e.g.
              }
           }
       }
    }

Or this structure could be separate from schema content, but could be added to new DH instance as you have it:

const uiConfig = { ...

What this would do is enable better code synchronization and not have it that people are manually adapting their code to match a change or deprecation in a class or slot reference.

@ddooley
Copy link
Collaborator

ddooley commented Feb 11, 2023

Your dynamic OLS lookup example looks neat; I assume the query part of it remains to be flushed out? Here I can see why we wouldn't necessarily want references to the widget baked into the LinkML schema. In other words, it seems much more consumer application specific whether users can be provided with application functionality to do dynamic lookups for particular fields, given their particular agency/project needs, their firewall etc, .... but ... say we had an open source such as OLS that could broadly be used for term lookup and OLS had no objections to serving all comers, then I'm also tempted to allow the LinkML spec to include the details of invoking that widget on a particular slot, again via annotations on that slot in a similar fashion to above? But maybe that's a misstep - all widget-specific configuration needs to be kept out of a schema itself? But perhaps we could ensure the Widget specific config can then contain an echo of the schema class/slot structure just for the fields that it pertains to?!

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

Successfully merging this pull request may close these issues.

2 participants