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

Plugin for ParameterRow can't seem to wrapComponent correctly #3968

Closed
awalsh-broadsoft opened this issue Nov 30, 2017 · 13 comments
Closed

Plugin for ParameterRow can't seem to wrapComponent correctly #3968

awalsh-broadsoft opened this issue Nov 30, 2017 · 13 comments

Comments

@awalsh-broadsoft
Copy link

Q A
Bug or feature request? Bug/Support
Which Swagger/OpenAPI version? 3.0.0
Which Swagger-UI version? 3.5
How did you install Swagger-UI? Tomcat
Which browser & version? Chrome
Which operating system? Windows 10 Pro

Demonstration API definition

I'm attempting to create a plugin using wrapComponent for ParameterRow. I have the top bar replaced with a new one, so I'm pretty sure my setup is working. However, it seems like I can't do a wrapComponent on ParameterRow.

class ParameterRow extends Component {
...Make some changes...
}

export const MyParameterRowPlugin = function() {
  return {
    wrapComponents: {
      ParameterRow
    }
  }
}

Here's my webpack.config.js:

const webpack = require('webpack')
const path = require('path')

module.exports = {
  entry: {
    'swagger-ui-broadsoft': [
      './src/index.js'
    ]
  },

  output: {
    path: path.join(__dirname, 'dist'),
    library: 'MySwaggerUI',
    libraryTarget: 'umd',
    filename: 'my-swagger-ui.min.js'
  },

  externals: (ctx, req, next) => {
    next(null, false)
  },

  module: {
    loaders: [{
      test: /\.js(x)?$/,
      loader: 'babel-loader',
      exclude: [
        /node_modules/
      ],
      query: {
        presets: ['react', 'es2015', 'stage-2']
      }
    },{
      test: /\.(png|jpg|jpeg|gif|svg)(\?.*)?$/,
      loader: "url-loader?limit=10000"
    }]
  },

  resolve: {
    modules: ['node_modules'],
    extensions: ['.js', '.json']
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production')
      }
    })
  ]
}

And my index.js:

import * as topbar from "./MyTopbarPlugin.js"
import * as queryparam from "./MyParameterRowPlugin.js"

module.exports.MyTopbarPlugin = topbar.MyTopbarPlugin;
module.exports.MyParameterRowPlugin = queryparam.MyParameterRowPlugin ;

Any ideas?

Expected Behavior

The parameter row's behavior should change.

Current Behavior

The parameter row's behavior is unchanged.

Context

I'm wanting to change the parameter row so that any parameter with a "schema" creates a "ParamBody". This behavior should happen regardless of whether or not the "in" has "body" as it's value.

@thompsongl
Copy link
Contributor

I think the problem stems from components vs wrapComponents plugins.

wrapComponents expects a function that returns a component:

export const MyParameterRowPlugin = function() {
  return {
    wrapComponents: {
      ParameterRow: (Original, system) => {
        return class ParameterRowWrap extends Component {
        ...Make some changes...
        }
      }
    }
  }
}

Whereas components expects a component (like you currently have):

class ParameterRow extends Component {
...Make some changes...
}

export const MyParameterRowPlugin = function() {
  return {
    components: {
      ParameterRow
    }
  }
}

Also, I've found that modifying/overriding core components needs to happen in presets instead of plugins.

@shockey
Copy link
Contributor

shockey commented Dec 5, 2017

@thompsongl, thanks for jumping in here 😄 this is correct, wrapComponent's signature is (Ori, system) => (props) => ReactElement, while component's is just props => ReactElement.

Speaking of this... I'm going to finally do the finishing touches on my docs overhaul so we can get the plugin API information out there.

As for the preset vs. plugin thing.. @thompsongl, that shouldn't be happening. Can you give me a quick example to test with?

@shockey
Copy link
Contributor

shockey commented Dec 6, 2017

@thompsongl scratch that, I put together a failing test for it. Yeah, looks like something's weird with wrapComponents that cross the presets/plugins boundary, we never noticed this in the core because all our stuff goes inside of the ApisPreset.

I'm working on a fix now.

@shockey
Copy link
Contributor

shockey commented Dec 6, 2017

OK, merged 🎉

the wrapComponents documentation is here: https://github.com/swagger-api/swagger-ui/blob/ft/docs/docs/customization/plugin-api.md#wrap-components

@awalsh-broadsoft, let me know if this documentation doesn't get you unstuck!

@awalsh-broadsoft
Copy link
Author

@thompsongl My example above doesn't show that I had tried what you described. My bad. I was fidgeting with the code so much that I must have ended up with it in that state.

I appreciate the input from both of you, and thanks for finding it.
I'll update with my findings after the next release.

@awalsh-broadsoft
Copy link
Author

awalsh-broadsoft commented Dec 11, 2017

Oh shoot. Now I realize you weren't talking to me when you said that you merged a fix.

So I had already tried what @thompsongl suggested before submitting the issue. When it came time to create the issue, I copied what I had but with some mistakes.

Basically, I'm still seeing the problem with not being able to wrap ParameterRow even with using it the way you've suggested.

import React, { Component } from "react"
import PropTypes from "prop-types"
import window from "swagger-ui"

export const QueryParamSchemaPlugin = function() {
  return {
    wrapComponents: {
      ParameterRow: (Original, system) => (props) => {
        class MyParameterRow extends Component {
          ...Make some changes...
        }
        return MyParameterRow
      }
    }
  }
}

Are either of you able to wrap the ParameterRow component?

@shockey
Copy link
Contributor

shockey commented Dec 11, 2017

@awalsh-broadsoft - I hate that this is a problem, and I've added this to #3393... but I'm pretty sure what's going wrong is that ParameterRow is named parameterRow internally.

Try changing your plugin export to this:

export const MyParameterRowPlugin = function() {
  return {
    wrapComponents: {
      parameterRow: ParameterRow
    }
  }
}

Let me know if this works - if so, I'll make fixing the case sensitivity a priority. This is a silly particular that shouldn't be getting folks stuck!

@awalsh-broadsoft
Copy link
Author

That got me unstuck. I appreciate the work around and will keep an eye out for the fix in the future. Thank you so much. :)

@awalsh-broadsoft
Copy link
Author

Alright, sorry to come right back, but it looks like I'm stuck again.

As soon as I started using "parameterRow", I started getting an error saying, "n.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object."

I couldn't figure out what I'm doing wrong, and googling for answers didn't turn up much. I even just copied and pasted straight from the existing parameter-row.jsx file in swagger-ui to see if that would prevent the error. Whatever the reason I can't seem to get around it. Any ideas?

@awalsh-broadsoft
Copy link
Author

Even if I just try returning the original, it still seems to error.

export const QueryParamSchemaPlugin = function() {
  return {
    wrapComponents: {
      parameterRow: (Original, system) => (props) => {
        return Original
      }
    }
  }
}

@thompsongl
Copy link
Contributor

thompsongl commented Dec 12, 2017

@awalsh-broadsoft You're going to want to do either:

parameterRow: (Original, system) => (props) => {
    return <Original {...props} />; // return an element
    // return <MyParameterRow />;
}

Or

parameterRow: (Original, system) => {
    return Original; // return a class or function
    // return MyParameterRow;
}

@awalsh-broadsoft
Copy link
Author

That seems to have done it. Thanks so much for your patience.

@shockey
Copy link
Contributor

shockey commented Dec 12, 2017

Awesome, glad it's all sorted.

Thanks for your help here, @thompsongl!

Closing - feel free to bump this thread if anything else comes up.

@shockey shockey closed this as completed Dec 12, 2017
@lock lock bot locked and limited conversation to collaborators Jul 2, 2019
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

3 participants