We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Non blocking widget refresh indicator
When refreshing a dashboard widget the previous results are hidden by the refresh animation. This can be an issue when refreshing a dashboard frequently, as you might happen to see the spinner for long period of times.

To solve this we can keep showing the old data until new one is available, while showing some indication that refresh is in progress.

Is the following animation enough?

![](http://g.recordit.co/CyccMD6dFc.gif)
After refreshing a dashboard, widgets become draggable even when not in edit mode


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `redash/handlers/widgets.py`
Content:
```
1 import json
2 
3 from flask import request
4 from redash import models
5 from redash.handlers.base import BaseResource
6 from redash.permissions import (require_access,
7                                 require_object_modify_permission,
8                                 require_permission, view_only)
9 
10 
11 class WidgetListResource(BaseResource):
12     @require_permission('edit_dashboard')
13     def post(self):
14         """
15         Add a widget to a dashboard.
16 
17         :<json number dashboard_id: The ID for the dashboard being added to
18         :<json visualization_id: The ID of the visualization to put in this widget
19         :<json object options: Widget options
20         :<json string text: Text box contents
21         :<json number width: Width for widget display
22 
23         :>json object widget: The created widget
24         """
25         widget_properties = request.get_json(force=True)
26         dashboard = models.Dashboard.get_by_id_and_org(widget_properties.pop('dashboard_id'), self.current_org)
27         require_object_modify_permission(dashboard, self.current_user)
28 
29         widget_properties['options'] = json.dumps(widget_properties['options'])
30         widget_properties.pop('id', None)
31         widget_properties['dashboard'] = dashboard
32 
33         visualization_id = widget_properties.pop('visualization_id')
34         if visualization_id:
35             visualization = models.Visualization.get_by_id_and_org(visualization_id, self.current_org)
36             require_access(visualization.query_rel.groups, self.current_user, view_only)
37         else:
38             visualization = None
39 
40         widget_properties['visualization'] = visualization
41 
42         widget = models.Widget(**widget_properties)
43         models.db.session.add(widget)
44         models.db.session.commit()
45 
46         models.db.session.commit()
47         return {'widget': widget.to_dict()}
48 
49 
50 class WidgetResource(BaseResource):
51     @require_permission('edit_dashboard')
52     def post(self, widget_id):
53         """
54         Updates a widget in a dashboard.
55         This method currently handles Text Box widgets only.
56 
57         :param number widget_id: The ID of the widget to modify
58 
59         :<json string text: The new contents of the text box
60         """
61         widget = models.Widget.get_by_id_and_org(widget_id, self.current_org)
62         require_object_modify_permission(widget.dashboard, self.current_user)
63         widget_properties = request.get_json(force=True)
64         widget.text = widget_properties['text']
65         widget.options = json.dumps(widget_properties['options'])
66         models.db.session.commit()
67         return widget.to_dict()
68 
69     @require_permission('edit_dashboard')
70     def delete(self, widget_id):
71         """
72         Remove a widget from a dashboard.
73 
74         :param number widget_id: ID of widget to remove
75         """
76         widget = models.Widget.get_by_id_and_org(widget_id, self.current_org)
77         require_object_modify_permission(widget.dashboard, self.current_user)
78         models.db.session.delete(widget)
79         models.db.session.commit()
80
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/redash/handlers/widgets.py b/redash/handlers/widgets.py
--- a/redash/handlers/widgets.py
+++ b/redash/handlers/widgets.py
@@ -44,7 +44,7 @@
         models.db.session.commit()
 
         models.db.session.commit()
-        return {'widget': widget.to_dict()}
+        return widget.to_dict()
 
 
 class WidgetResource(BaseResource):

{"golden_diff": "diff --git a/redash/handlers/widgets.py b/redash/handlers/widgets.py\n--- a/redash/handlers/widgets.py\n+++ b/redash/handlers/widgets.py\n@@ -44,7 +44,7 @@\n         models.db.session.commit()\n \n         models.db.session.commit()\n-        return {'widget': widget.to_dict()}\n+        return widget.to_dict()\n \n \n class WidgetResource(BaseResource):\n", "issue": "Non blocking widget refresh indicator\nWhen refreshing a dashboard widget the previous results are hidden by the refresh animation. This can be an issue when refreshing a dashboard frequently, as you might happen to see the spinner for long period of times.\r\n\r\nTo solve this we can keep showing the old data until new one is available, while showing some indication that refresh is in progress.\r\n\r\nIs the following animation enough?\r\n\r\n![](http://g.recordit.co/CyccMD6dFc.gif)\nAfter refreshing a dashboard, widgets become draggable even when not in edit mode\n\n", "before_files": [{"content": "import json\n\nfrom flask import request\nfrom redash import models\nfrom redash.handlers.base import BaseResource\nfrom redash.permissions import (require_access,\n                                require_object_modify_permission,\n                                require_permission, view_only)\n\n\nclass WidgetListResource(BaseResource):\n    @require_permission('edit_dashboard')\n    def post(self):\n        \"\"\"\n        Add a widget to a dashboard.\n\n        :<json number dashboard_id: The ID for the dashboard being added to\n        :<json visualization_id: The ID of the visualization to put in this widget\n        :<json object options: Widget options\n        :<json string text: Text box contents\n        :<json number width: Width for widget display\n\n        :>json object widget: The created widget\n        \"\"\"\n        widget_properties = request.get_json(force=True)\n        dashboard = models.Dashboard.get_by_id_and_org(widget_properties.pop('dashboard_id'), self.current_org)\n        require_object_modify_permission(dashboard, self.current_user)\n\n        widget_properties['options'] = json.dumps(widget_properties['options'])\n        widget_properties.pop('id', None)\n        widget_properties['dashboard'] = dashboard\n\n        visualization_id = widget_properties.pop('visualization_id')\n        if visualization_id:\n            visualization = models.Visualization.get_by_id_and_org(visualization_id, self.current_org)\n            require_access(visualization.query_rel.groups, self.current_user, view_only)\n        else:\n            visualization = None\n\n        widget_properties['visualization'] = visualization\n\n        widget = models.Widget(**widget_properties)\n        models.db.session.add(widget)\n        models.db.session.commit()\n\n        models.db.session.commit()\n        return {'widget': widget.to_dict()}\n\n\nclass WidgetResource(BaseResource):\n    @require_permission('edit_dashboard')\n    def post(self, widget_id):\n        \"\"\"\n        Updates a widget in a dashboard.\n        This method currently handles Text Box widgets only.\n\n        :param number widget_id: The ID of the widget to modify\n\n        :<json string text: The new contents of the text box\n        \"\"\"\n        widget = models.Widget.get_by_id_and_org(widget_id, self.current_org)\n        require_object_modify_permission(widget.dashboard, self.current_user)\n        widget_properties = request.get_json(force=True)\n        widget.text = widget_properties['text']\n        widget.options = json.dumps(widget_properties['options'])\n        models.db.session.commit()\n        return widget.to_dict()\n\n    @require_permission('edit_dashboard')\n    def delete(self, widget_id):\n        \"\"\"\n        Remove a widget from a dashboard.\n\n        :param number widget_id: ID of widget to remove\n        \"\"\"\n        widget = models.Widget.get_by_id_and_org(widget_id, self.current_org)\n        require_object_modify_permission(widget.dashboard, self.current_user)\n        models.db.session.delete(widget)\n        models.db.session.commit()\n", "path": "redash/handlers/widgets.py"}], "after_files": [{"content": "import json\n\nfrom flask import request\nfrom redash import models\nfrom redash.handlers.base import BaseResource\nfrom redash.permissions import (require_access,\n                                require_object_modify_permission,\n                                require_permission, view_only)\n\n\nclass WidgetListResource(BaseResource):\n    @require_permission('edit_dashboard')\n    def post(self):\n        \"\"\"\n        Add a widget to a dashboard.\n\n        :<json number dashboard_id: The ID for the dashboard being added to\n        :<json visualization_id: The ID of the visualization to put in this widget\n        :<json object options: Widget options\n        :<json string text: Text box contents\n        :<json number width: Width for widget display\n\n        :>json object widget: The created widget\n        \"\"\"\n        widget_properties = request.get_json(force=True)\n        dashboard = models.Dashboard.get_by_id_and_org(widget_properties.pop('dashboard_id'), self.current_org)\n        require_object_modify_permission(dashboard, self.current_user)\n\n        widget_properties['options'] = json.dumps(widget_properties['options'])\n        widget_properties.pop('id', None)\n        widget_properties['dashboard'] = dashboard\n\n        visualization_id = widget_properties.pop('visualization_id')\n        if visualization_id:\n            visualization = models.Visualization.get_by_id_and_org(visualization_id, self.current_org)\n            require_access(visualization.query_rel.groups, self.current_user, view_only)\n        else:\n            visualization = None\n\n        widget_properties['visualization'] = visualization\n\n        widget = models.Widget(**widget_properties)\n        models.db.session.add(widget)\n        models.db.session.commit()\n\n        models.db.session.commit()\n        return widget.to_dict()\n\n\nclass WidgetResource(BaseResource):\n    @require_permission('edit_dashboard')\n    def post(self, widget_id):\n        \"\"\"\n        Updates a widget in a dashboard.\n        This method currently handles Text Box widgets only.\n\n        :param number widget_id: The ID of the widget to modify\n\n        :<json string text: The new contents of the text box\n        \"\"\"\n        widget = models.Widget.get_by_id_and_org(widget_id, self.current_org)\n        require_object_modify_permission(widget.dashboard, self.current_user)\n        widget_properties = request.get_json(force=True)\n        widget.text = widget_properties['text']\n        widget.options = json.dumps(widget_properties['options'])\n        models.db.session.commit()\n        return widget.to_dict()\n\n    @require_permission('edit_dashboard')\n    def delete(self, widget_id):\n        \"\"\"\n        Remove a widget from a dashboard.\n\n        :param number widget_id: ID of widget to remove\n        \"\"\"\n        widget = models.Widget.get_by_id_and_org(widget_id, self.current_org)\n        require_object_modify_permission(widget.dashboard, self.current_user)\n        models.db.session.delete(widget)\n        models.db.session.commit()\n", "path": "redash/handlers/widgets.py"}]}