Repository: equinor/webviz-core-components (language: python)

Issue:
Add "Report issue/improvement suggestion" button
If `webviz_core_compnents.PluginPlaceholder` supports a button for creating new issues (e.g. on GitHub), this could be increasingly useful in Webviz application when plugins start being included from different plugin projects.

On the `webviz-config` side, the link the user is directed to when clicking on the button could be taken from https://github.com/equinor/webviz-config/blob/3da48870d9e81d01400e60096cb7f991f10669e1/webviz_config/plugins/_utils.py#L18 (which already today comes from the plugin project's `setup.py`, e.g. https://github.com/equinor/webviz-subsurface/blob/00418643c004908a351dac3cfc29ced7aab3c196/setup.py#L92).


Discussion / hints:
On the `webviz-config` side of it, we can pre-populate the issue with different queries:
https://docs.github.com/en/github/managing-your-work-on-github/about-automation-for-issues-and-pull-requests-with-query-parameters#supported-query-parameters

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 372dd360..f07617c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [UNRELEASED] - YYYY-MM-DD
+### Added
+- [#130](https://github.com/equinor/webviz-core-components/pull/130) - Added feedback button to `WebvizPluginPlaceholder`. Added `href` and `target` properties to `WebvizToolbarButton`.
+
 ### Fixed
 - [#124](https://github.com/equinor/webviz-core-components/pull/124) - `SmartNodeSelector` now returns all selected tags (also invalid and duplicate ones) to parent.
 - [#123](https://github.com/equinor/webviz-core-components/pull/123) - Removed unused variables and added types to `SmartNodeSelector` and its tests.
diff --git a/src/demo/App.tsx b/src/demo/App.tsx
index d676e499..fe534c12 100644
--- a/src/demo/App.tsx
+++ b/src/demo/App.tsx
@@ -52,6 +52,10 @@ class App extends Component {
                     id={"placeholder"}
                     setProps={this.setProps}
                     tour_steps={steps}
+                    feedback_url={
+                        "https://github.com/equinor/webviz-core-components/issues/"
+                        + "new?title=New+feedback&body=Feedback+text&labels=userfeedback"
+                    }
                     deprecation_warnings={
                         [
                             {
diff --git a/src/lib/components/WebvizPluginPlaceholder/WebvizPluginPlaceholder.tsx b/src/lib/components/WebvizPluginPlaceholder/WebvizPluginPlaceholder.tsx
index df3b8504..97386d12 100644
--- a/src/lib/components/WebvizPluginPlaceholder/WebvizPluginPlaceholder.tsx
+++ b/src/lib/components/WebvizPluginPlaceholder/WebvizPluginPlaceholder.tsx
@@ -17,7 +17,8 @@ import {
     faCameraRetro,
     faExpand,
     faDownload,
-    faExclamationTriangle
+    faExclamationTriangle,
+    faCommentAlt
 } from "@fortawesome/free-solid-svg-icons";
 
 import WebvizToolbarButton from "./utils/WebvizToolbarButton";
@@ -42,6 +43,7 @@ const InnerWebvizPluginPlaceholder = (
         download,
         screenshot_filename,
         tour_steps,
+        feedback_url,
         data_requested,
         deprecation_warnings,
         setProps
@@ -219,6 +221,15 @@ const InnerWebvizPluginPlaceholder = (
                                 }
                             />
                         )}
+                    {buttons && buttons.includes("feedback") && feedback_url
+                        && (
+                            <WebvizToolbarButton
+                                icon={faCommentAlt}
+                                tooltip="Report issue / suggest improvement"
+                                href={feedback_url}
+                                target="blank"
+                            />
+                        )}
                     {deprecation_warnings.length > 0 && (
                         <WebvizToolbarButton
                             icon={faExclamationTriangle}
@@ -267,6 +278,7 @@ WebvizPluginPlaceholder.defaultProps = {
         "download",
         "guided_tour",
         "contact_person",
+        "feedback"
     ],
     contact_person: undefined,
     tour_steps: [],
@@ -274,6 +286,7 @@ WebvizPluginPlaceholder.defaultProps = {
     download: undefined,
     screenshot_filename: "webviz-screenshot.png",
     deprecation_warnings: [],
+    feedback_url: "",
     setProps: () => { return undefined },
 };
 
@@ -343,6 +356,11 @@ WebvizPluginPlaceholder.propTypes = {
         )
     ),
 
+    /**
+     * URL to feedback website.
+     */
+    feedback_url: PropTypes.string,
+
     /**
      * Dash-assigned callback that should be called whenever any of the
      * properties change
diff --git a/src/lib/components/WebvizPluginPlaceholder/utils/WebvizToolbarButton.tsx b/src/lib/components/WebvizPluginPlaceholder/utils/WebvizToolbarButton.tsx
index aa43a988..5be75bef 100644
--- a/src/lib/components/WebvizPluginPlaceholder/utils/WebvizToolbarButton.tsx
+++ b/src/lib/components/WebvizPluginPlaceholder/utils/WebvizToolbarButton.tsx
@@ -10,20 +10,36 @@ type WebvizToolbarButtonProps = {
     onClick?: (event: MouseEvent) => void;
     important?: boolean;
     tooltip?: string;
+    href?: string;
+    target?: string;
 };
 
-const WebvizToolbarButton: React.FC<WebvizToolbarButtonProps> = ({ icon, selected, onClick, important, tooltip }) => {
+const WebvizToolbarButton: React.FC<WebvizToolbarButtonProps> = ({
+    icon,
+    selected,
+    onClick,
+    important,
+    tooltip,
+    href,
+    target
+}) => {
+    const createIcon = (useOnClick: boolean) => (<FontAwesomeIcon
+        icon={icon}
+        className={classNames({
+            "webviz-config-plugin-button": true,
+            "webviz-config-plugin-button-selected": selected,
+            "webviz-config-plugin-button-important": important,
+        })}
+        onClick={useOnClick ? onClick : undefined}
+    />);
+
     return (
         <div className="webviz-config-tooltip-wrapper">
-            <FontAwesomeIcon
-                icon={icon}
-                className={classNames({
-                    "webviz-config-plugin-button": true,
-                    "webviz-config-plugin-button-selected": selected,
-                    "webviz-config-plugin-button-important": important,
-                })}
-                onClick={onClick}
-            />
+            {href ? (
+                <a href={href} target={target}>{createIcon(false)}</a>
+            ) : (
+                createIcon(true)
+            )}
             <div className="webviz-config-tooltip">
                 {tooltip}
             </div>
@@ -58,4 +74,14 @@ WebvizToolbarButton.propTypes = {
      * The callback function to triger when button is clicked.
      */
     onClick: PropTypes.func,
+
+    /**
+     * URL the button shall forward to.
+     */
+    href: PropTypes.string,
+
+    /**
+     * The target the URL defined in `href` is opened in.
+     */
+    target: PropTypes.string,
 };


Test patch:
diff --git a/tests/js/__snapshots__/WebvizPluginPlaceholder.test.tsx.snap b/tests/js/__snapshots__/WebvizPluginPlaceholder.test.tsx.snap
index a8f76ba6..9bc96b88 100644
--- a/tests/js/__snapshots__/WebvizPluginPlaceholder.test.tsx.snap
+++ b/tests/js/__snapshots__/WebvizPluginPlaceholder.test.tsx.snap
@@ -118,6 +118,7 @@ exports[`WebvizPluginPlaceholder Renders correctly (compare to snapshot in ./__s
           Guided tour
         </div>
       </div>
+      
       <div
         class="webviz-config-tooltip-wrapper"
       >