Skip to content
This repository has been archived by the owner on Jan 24, 2023. It is now read-only.

Feature json schema #2664

Conversation

hamzahamidi
Copy link
Contributor

@hamzahamidi hamzahamidi commented Jul 11, 2018

Description

ADD JSON schema form generator to service binding & instance
1
2

Motivation and Context

JSON Schema sent by the broker creator is used to generate forms which are used to generate the json parameters for the service binding & service instance.
This feature uses Angular 6 JSON Schema Form builder which generates forms from JSON schemas using Angular.
The library is compatible with version 4 of the JSON schema standard.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Docs update
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have followed the guidelines in CONTRIBUTING.md, including the required formatting of the commit message

@cfdreddbot
Copy link

Hey hamzahamidi!

Thanks for submitting this pull request! I'm here to inform the recipients of the pull request that you and the commit authors have already signed the CLA.

@codecov
Copy link

codecov bot commented Jul 11, 2018

Codecov Report

Merging #2664 into v2-master will decrease coverage by 21.23%.
The diff coverage is 48.89%.

@@              Coverage Diff               @@
##           v2-master    #2664       +/-   ##
==============================================
- Coverage      70.03%   48.79%   -21.24%     
==============================================
  Files            599      604        +5     
  Lines          25504    25892      +388     
  Branches        5765     5862       +97     
==============================================
- Hits           17862    12635     -5227     
- Misses          7642    13257     +5615

@richard-cox
Copy link
Contributor

Hi @hamzahamidi thanks for submitting this PR. Noticed that it currently uses a personal fork of the json schema form field project and that you've created a PR to get this merged back to origin (dschnelldavis/angular2-json-schema-form#295). Do you have a rough idea of when that might happen?

@hamzahamidi
Copy link
Contributor Author

hamzahamidi commented Jul 16, 2018

@richard-cox Thank you for your review. We tweaked the owner repo for angular2-json-schema-form & we're still waiting for the merge. This PR is still on progress. We added the JSON schema support for create schemas & we plan to do the same thing to update schemas

@hamzahamidi hamzahamidi force-pushed the feature-json-schema branch 3 times, most recently from c9e101d to 8283be4 Compare July 20, 2018 08:21
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
@hamzahamidi hamzahamidi force-pushed the feature-json-schema branch 2 times, most recently from 3f9ae8a to a448786 Compare July 25, 2018 08:47
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
@hamzahamidi
Copy link
Contributor Author

hamzahamidi commented Jul 25, 2018

@richard-cox This PR is ready for review. We switched the personal fork to angular6-json-schema-form because we faced an issue with enabling AOT in the old one.
Thank you.

@KlapTrap
Copy link
Contributor

KlapTrap commented Aug 2, 2018

Thanks, we will review this ASAP.

@hamzahamidi
Copy link
Contributor Author

status on the json-schema-form library
original author (@dschnelldavis) maintains the library by batch, and may take time to support merge angular6 and AOT support. See https://github.com/dschnelldavis/angular2-json-schema-form#contributions-and-future-development

If you like this library, need help, or want to contribute, let me know. I'm busy, so it sometimes takes me a long time to respond, but I will eventually get back to you. :-)

I initially proposed dschnelldavis/angular2-json-schema-form#295.
However, this PR did not include AOT support that required deeper changes, I created a hamzahamidi/Angular6-json-schema-form repo
This repo contains additional refactorings over dschnelldavis/angular2-json-schema-form
the plan is indeed to merge back effort with @dschnelldavis and the associated community. This convergence effort in underway into dschnelldavis/angular2-json-schema-form#302
I plan to maintain this new repo until the convergence with @dschnelldavis and the community is finalized
Note that my contract with Orange ends of august and that Orange has not yet identified engineering resources to contribute to stratos yet. If you have a way to priorize review and merging of this PR in the coming days, that will much help me.

Copy link
Contributor

@richard-cox richard-cox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We apologise for the amount of time it's taken us to start reviewing this PR. Personally I was hoping that the angular2 forms repo would merge your changes, but appreciate you're doing all you can get your changes merged and that your fork is getting some great traction. It's really good to see it already has multiple contributors and stars. I have a question regarding the angular6-json-schema-form's npm entry though, have all people that have update access to it taken steps to secure their account (such as enabling two-step authentication)?

I've had a quick look through using the schema from https://hamidihamza.com/Angular6-json-schema-form/. There's mostly 'best practise' like comments, nothing major. In addition...

  • Adding text to fields in the generated form correctly updates the JSON parameters text above, however the reverse does not happen.
  • When the form is invalid (for example a require field such as last_name is missing) the step is still valid (stepper next button is enabled).
  • There are some errors shown at the bottom. It feels like these should only be generic issues that are not associated with a specific field, else those errors should appear underneath the fields themselves. For example required field errors appear both beneath the field and in the list at the bottom. For a 'phone number' section a missing number is only shown in the list at the bottom, for example
should have required property 'last_name'
undefined.phone_numbers[0]: should have required property 'number'
specify-details-step.component.html:27 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'mat-form-field-should-float: false'. Current value: 'mat-form-field-should-float: true'.
  • There's a new class that's being applied to the mat-form-field-infix divs (see below) which breaks the width of fields in the list component (these are fixed width, but are ignored in favour of this new class). This might disappear when/if '@angular/flex-layout' goes?
mat-form-field .mat-form-field-wrapper .mat-form-field-flex .mat-form-field-infix {
    width: initial;
}

Overall .. some things to work through but it's looking really good!

@@ -46,6 +46,7 @@
"@angular/common": "6.0.3",
"@angular/compiler": "6.0.3",
"@angular/core": "6.0.3",
"@angular/flex-layout": "^6.0.0-beta.16",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like this is used within Stratos, however removing results in the following error

ERROR in ../../angular6-json-schema-form/angular6-json-schema-form.ts(38,53): Error during template compile of 'MaterialDesignFrameworkModule'
  Could not resolve @angular/flex-layout relative to /home/richard/dev/github/stratos-ui-orange-cloudfoundry/node_modules/angular6-json-schema-form/angular6-json-schema-form.d.ts..

Should this be a dependency of angular6-json-schema-form?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the material design module uses @angular/flex-layout. I'm open to better approachs

src/frontend/app/core/cf-api-svc.types.ts Show resolved Hide resolved
}));
};

export const prettyValidationErrors = (formValidationErrors) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formValidationErrors needs a type, that would open up the easier formValidationErrors.forEach iteration function. If you're feeling fancy you could even use formValidationErrors.reduce instead, which would both iterate over formValidationErrors and output the errorArray

<mat-card-content>
<json-schema-form loadExternalAssets="true" [options]="jsonFormOptions" [schema]="schema" [framework]="selectedFramework" (validationErrors)="validationErrors($event)" (onChanges)="onFormChange($event)">
</json-schema-form>
<div *ngIf="!!prettyValidationErrors" class="data-bad" [innerHTML]="prettyValidationErrors"></div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For class names we use BEM notation (for an intro see http://getbem.com/introduction/). At the moment we have BEM checking turned off in our pipeline, but at some point in the future we'd like to turn it back on again.

@@ -35,6 +36,14 @@ export class BindAppsStepComponent implements OnDestroy, AfterContentInit {
stepperForm: FormGroup;
apps$: Observable<APIResource<IApp>[]>;
guideText = 'Specify the application to bind (Optional)';

selectedFramework = 'material-design';
schema: any;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible it would be nice to type the fields and function params in this class.

</form>
<div *ngIf="!!schema" class="json-schema">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a fair bit of duplication between this step and bind app (html, input, error handling, etc). Could the common parts be pulled out into a new component ServiceBindingForm? This would remove a lot of duplicated html, plumming in the component's code and i think the possibly the need for the scss mixins

onEnter = () => {
onEnter = (selectedService$?) => {
if (selectedService$ instanceof Observable) {
this.selectedServiceSubscription = selectedService$
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above comment about using first() or changing to this.schema$ observable

if (selectedService$ instanceof Observable) {
this.selectedServiceSubscription = selectedService$
.subscribe(selectedService => {
this.schema = this.filterSchema(selectedService.entity.entity.schemas.service_binding.create.parameters);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the two places this is used need to check whether if schemas has a value (currently gives undefined exception for services without schemas`

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full exception: Cannot read property 'service_binding' of undefined

<div *ngIf="!!schema" class="json-schema">
<mat-card class="json-schema-form">
<mat-card-header>
<mat-card-title><b>Generated Form</b><button mat-button color="accent" (click)="showJsonSchema=!showJsonSchema">Json schema</button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The button needs some padding-left, to ensure the 'on hover' button background has space between itself and text. Should also consider whether this button is something we should hide in production. @KlapTrap thoughts?

if (selectedService$ instanceof Observable) {
this.selectedServiceSubscription = selectedService$
.subscribe(selectedService => {
if (!!this.modeService.isEditServiceInstanceMode()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're in edit mode, should the update section be used?

@gberche-orange
Copy link
Contributor

gberche-orange commented Aug 8, 2018

thanks @richard-cox and @KlapTrap for your review

Adding text to fields in the generated form correctly updates the JSON parameters text above, however the reverse does not happen.

Yes, this two way data binding would be quite nice UX. The related work can also for improve the update service instance/binding parameters by prepopulating the form with the params previously submitted by the user. These params values are provided by the new OSB 2.14 GET endpoints for fetching a Service Instance and Service Binding which is now exposed by CC API in the related service instance and service binding endpoints. Related stratos issue: #2121

@hamzahamidi started looking into this but could not yet complete this. This seems possible from
https://github.com/dschnelldavis/angular2-json-schema-form#additional-inputs-an-outputs
to specify the initial (data) values

<json-schema-form
  [schema]="yourJsonSchema"
  [layout]="yourJsonFormLayout"
  [(data)]="yourData"
...
</json-schema-form>

Initial study indicates that real-time two way binding might be hard to achieve. An alternative might be to offer users to either edit in plain text or form, possibly by switching tabs (see mock below that may still include a real-time read-only preview)
image

I'll let him provide more details, confirm feasibility and required work.

There are some errors shown at the bottom. It feels like these should only be generic issues that are not associated with a specific field, else those errors should appear underneath the fields themselves. For example required field errors appear both beneath the field and in the list at the bottom. For a 'phone number' section a missing number is only shown in the list at the bottom, for example

The errors at the bottom are global validation errors that the library can't easily associate to a single particular field. Common example are violations to attribute dependencies, or missing attributes (i.e. for which associated form entry is not yet displayed, as they are optional). Display of these errors is necessary for users to understand schema constraints violations (as field-attached validation messages would be insufficient).

@KlapTrap
Copy link
Contributor

KlapTrap commented Aug 8, 2018

Thanks for your input, I like the mock design, would love to see it in action.

We don’t mind picking up we’re you left off if you don’t quite get it finished before you’re off, you’ve already saved us a lot of time!

@gberche-orange
Copy link
Contributor

gberche-orange commented Aug 8, 2018

When the form is invalid (for example a require field such as last_name is missing) the step is still valid (stepper next button is enabled)

We had mixed feelings about systematically disabling the next button on validation violations (currently stratos allows params violating their schema), and rather imagined either a way to have users bypass validation violations if needed, through either:

  • the "Next" button to change its color (e.g. to red) and text to "Next (ignore schema violations)" on schema violations
  • Two buttons (possibly stacked): "Next" and "Next (ignore schema violations)" with "Next" being disabled on schema violations

Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
Signed-off-by: Hamza Hamidi <hamza.hamidi@orange.com>
@richard-cox
Copy link
Contributor

@gberche-orange Mocked functionality looks good. This might also help with the form validation + next issue, (next state tied to form state on form tab, whilst ignored on json tab).
@hamzahamidi I know your time is short and would love to understand any recent progress.

@gberche-orange
Copy link
Contributor

@richard-cox

Mocked functionality looks good. This might also help with the form validation + next issue, (next state tied to form state on form tab, whilst ignored on json tab).

From a user perspective, it would be useful to also see validation messages when editing raw json, something like the mock below. Maybe the form could be updated and generate the validation message when focus is lost from the json text, and/or when an explicit refresh button is clicked.

image

I know your time is short and would love to understand any recent progress.

Hamza is out of office (with limited connectivity to provide status on the last pushed commits) until next monday aug 27th, (he will be holding his internship dissertation defense on that week, so he'll have limited contribution capacity).

@richard-cox
Copy link
Contributor

Closing in favour of updated #3050

@richard-cox richard-cox closed this Oct 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs attention This PR needs attention
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants