Skip to content

Structure of ui.yaml #1725

@axelboc

Description

@axelboc

A discussion started in #1699 concerning the structure of ui.yaml. I think I've mentioned before that I'm not a huge fan of the following structure:

<namespace>:
  id: <namespace>
  components:
    - id: <some-id>
      <some-properties>
    - id: <some-id>
      <some-properties>

Two reasons:

  • In the front-end, we end up having to loop through the components to find the one with the ID we want.
  • If/when we introduce typing, it will be a nightmare, because it will look something like: components: { id: string; [key: string]: any }[], which is not very helpful.

I would prefer to have a clear, static structure that is tailored to the needs of the front-end:

sampleViewVideoControls: # camelCase
  snapshot:
    show: true
  drawGrid:
    show: true
    showVspace: false
    showHspace: true
  ...  
const showSnapshot = useSelector(state => state.uiproperties.sampleViewVideoControls.snapshot.show);

// instead of
const showSnapshot = useSelector(state => state.uiproperties.sampleViewVideoControls.components.find(c => c.id === 'snapshot').show);

I would also be in favor of having a near-zero config experience out of the box, which means having a default config that gets merged/overridden by the content of ui.yaml (in JS below, but could also be done in the back-end of course):

const DEFAULT_CONFIG = {
  sampleViewVideoControls: {
    snapshot: {
      show: true
    },
    // ...
  },
  // ...
};

const uiproperties = merge(DEFAULT_CONFIG, uiConfig);

EDIT: To clarify, this idea of a default config is to avoid putting that logic throughout the codebase. For instance, we really don't want the sample view component to have to know that if snapshot: { show: true } is not defined in the config, it means that the snapshot control should be shown...


Finally, we may want to think about versioning the configuration. Without versioning, we tend to fear making breaking changes to the config structure, and this is when technical debt creeps up. With versioning, we can support a few versions easily to give people time to upgrade — upgrading the config can then be done separately from upgrading MXCuBE-Web:

function upgradeUiConfig(uiConfig) {
  if (uiConfig.version === '2.1') {
    return {
      ...omit(uiConfig, 'oldProperty'),
      newProperty: uiConfig.oldProperty
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions