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

#7585: refactor of the Print plugin as a plugins container #7596

Merged
merged 10 commits into from
Dec 14, 2021

Conversation

mbarto
Copy link
Contributor

@mbarto mbarto commented Nov 23, 2021

Description

This PR is a refactor of the Print plugin, to allow for custom UI plugins to be included from projects.
Most of the printing dialog widgets have been refactored as subplugins of the Print plugin.

Some ancillary work has been included to improve usability:

  • support for different implementations of the same plugin in PluginsUtils.getPluginItems
  • support of testing lazy plugins with pluginsTestUtils.getLazyPluginForTest
  • getByXPath function (in Print-test.jsx to be eventually moved into a utility file) to allow a more react-testing-library like approach for testing
  • support for custom parameters (set in the spec params object) in PrintUtils.getMapfishPrintSpecification

Please check if the PR fulfills these requirements

What kind of change does this PR introduce? (check one with "x", remove the others)

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

Issue

#7585

What is the current behavior?

#7585

What is the new behavior?

Breaking change

Does this PR introduce a breaking change? (check one with "x", remove the other)

  • Yes, and I documented them in migration notes
  • No

Other useful information

@mbarto mbarto added this to the 2022.01.00 milestone Nov 23, 2021
@mbarto mbarto self-assigned this Nov 23, 2021
@mbarto mbarto force-pushed the printing_plugins_refactor branch from 5a5aa97 to 4dfd8db Compare November 23, 2021 16:03
@mbarto mbarto force-pushed the printing_plugins_refactor branch from 4dfd8db to 8d579a5 Compare November 23, 2021 16:24
@mbarto mbarto marked this pull request as ready for review November 23, 2021 16:40
Copy link
Member

@offtherailz offtherailz left a comment

Choose a reason for hiding this comment

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

It's a little scary to me to have too many plugins by default. We already had some doubts with timeline + playback.

Can I suggest to use plugin injection as replacement for defaults components when you have a specific target.
E.g. when a plugin as a target like the following in the containers:

{ target:  "TextInput"
|        "Layout"
|        "LegendOptions"
|        "Resolution"
|        "MapPreview"
|        "Option"

The (documented) convention of the plugin is that these target are replacements for default components.
I think this solution is more maintainable on the core.
What do you think?

@mbarto
Copy link
Contributor Author

mbarto commented Nov 24, 2021

@offtherailz how would you add a custom plugin in a specific position? For example between title and description in the current printing dialog?
I like using the target as a replacement, it gives more flexibility. Do you think we should also handle removal of a "default" widget ?

@offtherailz
Copy link
Member

offtherailz commented Nov 25, 2021

@offtherailz how would you add a custom plugin in a specific position? For example between title and description in the current printing dialog?

In this case I should replace the whole panel (TextInput??). If some panels may accept more options, maybe we can define a target for the panel content.I Don't know if it is a requirement

I think you can be able to:

  • Replace default panels
  • Add some panels

Moreover I read on mailing list they was asking for adding a button to save on cloud the pdf. So future we may also allow to add some buttons here and there.

Do you think we should also handle removal of a "default" widget ?

Now I think they are decoupled so every panel is idependent and I think it makes sense, Maybe injecting an null component for the target may work?

@mbarto
Copy link
Contributor Author

mbarto commented Nov 25, 2021

@offtherailz to summarize the changes you suggest should be:

  • leave the default (connected) components untouched in plugins/print/index.js
  • change Print.jsx to allow replacements (or removal) of those components via plugins with a documented target (removal happens if the plugin has a null component definition)
  • allow addition of custom plugins in predefined targets (e.g. left-panel, right-panel, etc.) as already done by this PR

Is it correct?

@offtherailz
Copy link
Member

Yes @mbarto , correct. Hope it makes the plugin more flexible and maintainable.

…iner, implemented override and removal of standard plugins
…iner, fix in Option to correctly use properties with path
@mbarto
Copy link
Contributor Author

mbarto commented Nov 29, 2021

@offtherailz I have updated the PR. The build is currently failing due to webpack/nodejs issues (I guess)

Comment on lines 129 to 134
PrintTextInputPlugin: require('../plugins/print/TextInput').default,
PrintLayoutPlugin: require('../plugins/print/Layout').default,
PrintLegendOptionsPlugin: require('../plugins/print/LegendOptions').default,
PrintResolutionPlugin: require('../plugins/print/Resolution').default,
PrintMapPreviewPlugin: require('../plugins/print/MapPreview').default,
PrintOptionPlugin: require('../plugins/print/Option').default
Copy link
Member

@offtherailz offtherailz Nov 30, 2021

Choose a reason for hiding this comment

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

My idea was not to include any plugin, but only allow to override by plugin injection, on demand. Having this big set of plugin to configure or customize a single plugin is a problem. Potentially makes the size of the plugins list explode.

I asked to have a plugin like :

{
    "name": "PluginCustomization",
    "containers": {
            "Print": {
                    target: "left-panel-accordion", // I suggested to have specific targets to replace specific components.
                    position:  "" 
                    Component: MyCustomization
            }
    }
}

…iner, moved the Null plugin in plugins/print, removed print subplugins from product plugins.js, updated docs
Copy link
Member

@offtherailz offtherailz left a comment

Choose a reason for hiding this comment

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

It's ok, now I understood what you did.

  • Please look ad my comments, I think that applying the changes everything will seems easier to configure and maintain
  • You can avoid to use createPlugin for every single panel in print folder, using directly the component (that is optionally connected to the state).
  • For targets use names with dashes for everything, for constiency, as you did for left-panel e.g. printoptions --> print-options, defaultbackgroundignore -> default-background-ignore

web/client/plugins/Print.jsx Outdated Show resolved Hide resolved
web/client/plugins/Print.jsx Outdated Show resolved Hide resolved
Comment on lines 103 to 150
* // Custom plugin added to the left-panel target
* {
* "name": "PrintTextInput",
* "id", "ExtraParam",
* "override": {
* "Print": {
* "target": "left-panel",
* "position": 1.5
* }
* },
* "cfg": {
* "property": "extra",
* "label": "Extra stuff",
* "placeholder": "Inserisci cose..."
* }
* }
*
* @example
* // Custom plugin replacing an existing target
* {
* "name": "PrintTextInput",
* "id", "ExtraParam",
* "override": {
* "Print": {
* "target": "name",
* "position": 1
* }
* },
* "cfg": {
* "property": "extra",
* "label": "Extra stuff",
* "placeholder": "Inserisci cose..."
* }
* }
*
* @example
* // Removal of an existing target
* {
* "name": "Null",
* "override": {
* "Print": {
* "target": "name",
* "position": 1
* }
* },
* "cfg": {
* }
* }
Copy link
Member

Choose a reason for hiding this comment

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

Instead of having 3 examples and a lot of configurations and code, I suggest to use one single plugin, with no component, using the multi-target support.
Please try it.

Suggested change
* // Custom plugin added to the left-panel target
* {
* "name": "PrintTextInput",
* "id", "ExtraParam",
* "override": {
* "Print": {
* "target": "left-panel",
* "position": 1.5
* }
* },
* "cfg": {
* "property": "extra",
* "label": "Extra stuff",
* "placeholder": "Inserisci cose..."
* }
* }
*
* @example
* // Custom plugin replacing an existing target
* {
* "name": "PrintTextInput",
* "id", "ExtraParam",
* "override": {
* "Print": {
* "target": "name",
* "position": 1
* }
* },
* "cfg": {
* "property": "extra",
* "label": "Extra stuff",
* "placeholder": "Inserisci cose..."
* }
* }
*
* @example
* // Removal of an existing target
* {
* "name": "Null",
* "override": {
* "Print": {
* "target": "name",
* "position": 1
* }
* },
* "cfg": {
* }
* }
// PrintCustomizations.js
const MyCustomPanel = () => <div>Hello, I am a custom component</div>
const MyCustomLayout = connect(mapStateToProps, dispatchToProps)(CustomLayoutSelector);
export default createPlugin('PrintCustomizations',
containers: [
// this entry allows to add a new panel between text input and accordion panel
{
Print: [{ // this entry add a panel
target: "left-panel",
position: 1.5,
Component: MyCustomPanel
},
// this entry allows to
{
target: "layout",
Component: MyCustomLayout
}, {
target: "map-preview", // To remove one component, simply create a component that returns null.
Component: () => null
}]);

Comment on lines +59 to +60
* To remove a widget, you have to include a Null plugin with the desired target.
* You can use the position to sort existing and custom items.
Copy link
Member

Choose a reason for hiding this comment

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

You can customize Print plugin by creating one custom plugin (or more) that modifies the existing components with your ones. You can configure this plugin in localConfig.json as usual.

mbarto and others added 3 commits November 30, 2021 15:35
Co-authored-by: Lorenzo Natali <offtherailz@gmail.com>
Co-authored-by: Lorenzo Natali <offtherailz@gmail.com>
@tdipisa
Copy link
Member

tdipisa commented Dec 14, 2021

This PR has been merged without an approval @mbarto. @offtherailz please check it as soon as you can.

@offtherailz
Copy link
Member

My review was on 2 points:

  • Please look ad my comments, I think that applying the changes everything will seems easier to configure and maintain
  • For targets use names with dashes for everything, for constiency, as you did for left-panel e.g. printoptions --> print-options, defaultbackgroundignore -> default-background-ignore <-- I did it with my comments

These are missing:

  • You can avoid to use createPlugin for every single panel in print folder, using directly the component (that is optionally connected to the state). <-- this seems not to be done, but it is a simplification.
  • This comment - related to the avoid of using createPlugin with an example and some documentation #7585: refactor of the Print plugin as a plugins container #7596 (comment)

These changes are not mandatory for the functionality itself, but simplify a lot the current solution, that is very tricky.
If you missed this point in error @mbarto can you open a separate issue for that?
If otherwise you are against these requests for any reason (time, technical issues or other) please feel free to reply, but don't ignore them.

@mbarto
Copy link
Contributor Author

mbarto commented Dec 14, 2021

These are missing:

  • You can avoid to use createPlugin for every single panel in print folder, using directly the component (that is optionally connected to the state). <-- this seems not to be done, but it is a simplification.

If you look at the code you will see that each panel exports both a component and a plugin (as a default).
The component is used in index.js (this I suppose is what you were asking for), while the plugin can be used in project (and it will be used for the client I am doing this work for). Those plugins definition are not included in the product plugins.js (as you requested).

I didn't commit your suggestion directly, but if you look again at the example, if has been replaced by something very similar to yours, but verified and tested.

These changes are not mandatory for the functionality itself, but simplify a lot the current solution, that is very tricky. If you missed this point in error @mbarto can you open a separate issue for that? If otherwise you are against these requests for any reason (time, technical issues or other) please feel free to reply, but don't ignore them.

That said, feel free to remove my admin commit rights from the project if you prefer.

@offtherailz
Copy link
Member

If you look at the code you will see that each panel exports both a component and a plugin (as a default).
The component is used in index.js (this I suppose is what you were asking for), while the plugin can be used in project (and it will be used for the client I am doing this work for). Those plugins definition are not included in the product plugins.js (as you requested).

So all that createPlugins can be removed. They are not used and they are not documented in print plugin, It is only confusing.

Or there is some reason to keep them?

I didn't commit your suggestion directly, but if you look again at the example, if has been replaced by something very similar to yours, but verified and tested.

Great, I was confused by the double export (I said it was only confusing).

That said, feel free to remove my admin commit rights from the project if you prefer.

Please don't misunderstand me, I mean you may ask to me if you was in a hurry or what else. We would find a way to clarify and maybe split this clean up in 2.
I'd say yes, for sure.
Merging without telling anything only confuses more, and for async work we need trust and clarity.

@tdipisa tdipisa added tmp and removed tmp labels Feb 11, 2022
@tdipisa tdipisa added the Print label Mar 7, 2022
@allyoucanmap allyoucanmap mentioned this pull request Aug 9, 2024
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants