accordproject / web-components

React Components for Accord Project
Apache License 2.0
119 stars 99 forks source link

feat(concerto): Add Model Builder visitor and example story #353

Closed mttrbrts closed 3 years ago

mttrbrts commented 3 years ago

This PR extends ui-concerto to provide a "Model Builder" which allows users to create new Concerto models using a graphical form-based experience over the textual-format. This change also adds several related bug fixes and improvements.

image

Fixes #8

Changes

New visitor, ModelBuilderVisitor

The new visitor provides a more compact representation for the concerto.metadata models. This also serves as an exemplar for how developers could extend the default visitor for their own rendering code for custom models.

import { ConcertoForm, ModelBuilderVisitor } from '@accordproject/ui-concerto';
...
<ConcertoForm
  ...
  options={{
    ...,
    visitor: new ModelBuilderVisitor()
  }}
/>

Improvements to UX for large and nested array elements and classes.

Previously, class elements were not clear (see Address), and the action buttons for array elements caused confusion when the element was large (i.e. it wasn't clear which element the button corresponded to). Before: image

After image

New @FormEditor decorators

  1. @FormEditor("title", "My Field Name") - This decorator allows the modeller to explicitly specify the field title that should be used in the form, rather than the auto-generated title from the property name.
  2. @FormEditor("selectOptions", "types") - This decorator allows a developer to specify a set of dropdown selection options to be used instead of an input field for String properties. The value "types" is a key to the options parameter that is provided to the ConcertoForm component. e.g.
    <ConcertoForm
    ...
    options={{
    ...,
      customSelectors: {
        types: [
          { text: 'Contract', value: 'org.accordproject.cicero.contract.AccordContract' },
          { text: 'Party', value: 'org.accordproject.cicero.contract.AccordParty' }
        ]
    }
    }}
    />
  3. @FormEditor("defaultSubclass","concerto.metamodel.ConceptDeclaration") - This decorator allows the modeller to explicitly choose the default sub-class for an abstract type. This overrides the default behaviour which selects the first concrete sub-class for an abstract type when generating an instance.

Support for Validators on String fields

If a model property includes a regex validator. The generated model now displays a simply validation warning by highlighting the field. This could be extended to provide richer validation and messages, however this requires deeper consideration of the form validation in general.

Kapture 2021-07-14 at 10 34 39

Change default checkbox appearance

Previously checkboxes were rendered as toggles, now the default is for a checkbox representation. Developers can explicitly set the checkbox style with the new checkboxStyle option.

<ConcertoForm
  ...
  options={{
    ...,
   checkboxStyle: 'toggle',
  }}
/>

Bug Fixes

  1. Fixes a bug where values in nested arrays were not updated properly when adding a new element to the array. Fixed by properly serializing the stack to a lodash path using lodash.topath.
  2. Fixes use of factory methods newConcept and newResource to omit id parameter. https://github.com/accordproject/web-components/pull/353/files#diff-7767cb5470a92481598fd4e18339e4fcfd9dee2f5b3d243a6aebbe713360c7faR136
  3. Fixes a bug where getDefaultValue did not respect the includeOptionalFields and includeSampleData options.

Flags

Author Checklist

dselman commented 3 years ago

A couple of things I spotted playing with the Storybook (very cool). These can be follow ups?

  1. Can't create enums
  2. Can't specify the namespace for a model file
  3. Can't create a class and then reference it in a subsequently created class. E.g create an Address, and then create a Person that has-an Address. Type references (object types, super types) could be modelled using --> and then use a RelationshipProvider to dynamically return the compatible types based on the ModelFile being edited: https://github.com/accordproject/web-components/blob/0667d024f07bc6b4293589047c4ad6851eb73bcf/packages/ui-concerto/src/components/fields.js#L104
  4. Support for adding decorators?
  5. No ability to clear the super type once it has been specified by selecting a type in the drop down
jeromesimeon commented 3 years ago

A couple of things I spotted playing with the Storybook (very cool). These can be follow ups?

  1. Can't create enums
  2. Can't specify the namespace for a model file
  3. Can't create a class and then reference it in a subsequently created class. E.g create an Address, and then create a Person that has-an Address. Type references (object types, super types) could be modelled using --> and then use a RelationshipProvider to dynamically return the compatible types based on the ModelFile being edited: https://github.com/accordproject/web-components/blob/0667d024f07bc6b4293589047c4ad6851eb73bcf/packages/ui-concerto/src/components/fields.js#L104
  4. Support for adding decorators?
  5. No ability to clear the super type once it has been specified by selecting a type in the drop down

Awesome indeed. To me 1.2.3.5. sound really important for MVP.

I would add:

  1. this relies on an unpublished (new) version of the metamodel. I opened a PR for this here: https://github.com/accordproject/models/pull/137
  2. Allow nested complex types, not just relationships to them (which will only work for identifiable types)
  3. Rebase with master? I see some conflicts.
mttrbrts commented 3 years ago

I've addressed 2 & 5. The others can be addressed separately.

@jeromesimeon

  1. Is this different to the "Object" field type?
  2. Where do you see conflicts, please? I've already rebased.
jeromesimeon commented 3 years ago

I've addressed 2 & 5. The others can be addressed separately.

@jeromesimeon

  1. Is this different to the "Object" field type?

ah, yes that's what it is! I had missed it in the demo.

  1. Where do you see conflicts, please? I've already rebased.

Seeing this in the UI:

Screen Shot 2021-07-15 at 6 28 03 PM
jeromesimeon commented 3 years ago

@mttrbrts @dselman I'm going to merge this so I can do further work on it!