We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Xtheme: there is no warning for usaved changes when switching between plugins
To reproduce:
1. Edit some content in Xtheme editor
2. Select another plugin without saving
3. See your changes to disappear

There probably should be warning before switching plugins when you have unsaved information.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `shuup/campaigns/admin_module/forms/_basket.py`
Content:
```
1 # This file is part of Shuup.
2 #
3 # Copyright (c) 2012-2019, Shoop Commerce Ltd. All rights reserved.
4 #
5 # This source code is licensed under the OSL-3.0 license found in the
6 # LICENSE file in the root directory of this source tree.
7 from django import forms
8 from django.db.models import Q
9 from django.utils.translation import ugettext_lazy as _
10 
11 from shuup.admin.shop_provider import get_shop
12 from shuup.admin.supplier_provider import get_supplier
13 from shuup.campaigns.models import BasketCampaign, Coupon
14 
15 from ._base import BaseCampaignForm, QuickAddCouponSelect
16 
17 
18 class BasketCampaignForm(BaseCampaignForm):
19     class Meta(BaseCampaignForm.Meta):
20         model = BasketCampaign
21 
22     def __init__(self, *args, **kwargs):
23         super(BasketCampaignForm, self).__init__(*args, **kwargs)
24 
25         coupons = Coupon.objects.filter(
26             Q(active=True, shop=get_shop(self.request)),
27             Q(campaign=None) | Q(campaign=self.instance),
28         )
29         supplier = get_supplier(self.request)
30         if supplier:
31             coupons = coupons.filter(supplier=supplier)
32 
33         coupon_code_choices = [('', '')] + list(coupons.values_list("pk", "code"))
34         field_kwargs = dict(choices=coupon_code_choices, required=False)
35         field_kwargs["help_text"] = _("Define the required coupon for this campaign.")
36         field_kwargs["label"] = _("Coupon")
37         field_kwargs["widget"] = QuickAddCouponSelect(editable_model="campaigns.Coupon")
38         if self.instance.pk and self.instance.coupon:
39             field_kwargs["initial"] = self.instance.coupon.pk
40 
41         self.fields["coupon"] = forms.ChoiceField(**field_kwargs)
42 
43         # the supplier will be, by default, the current one
44         if supplier:
45             self.fields["supplier"].widget = forms.HiddenInput()
46 
47     def clean_coupon(self):
48         coupon = self.cleaned_data.get("coupon")
49         if coupon:
50             coupon = Coupon.objects.get(pk=coupon)
51         return coupon or None
52 
53     def clean_supplier(self):
54         return self.cleaned_data.get("supplier") or get_supplier(self.request)
55
```
--- 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/shuup/campaigns/admin_module/forms/_basket.py b/shuup/campaigns/admin_module/forms/_basket.py
--- a/shuup/campaigns/admin_module/forms/_basket.py
+++ b/shuup/campaigns/admin_module/forms/_basket.py
@@ -30,7 +30,7 @@
         if supplier:
             coupons = coupons.filter(supplier=supplier)
 
-        coupon_code_choices = [('', '')] + list(coupons.values_list("pk", "code"))
+        coupon_code_choices = [('', '---------')] + list(coupons.values_list("pk", "code"))
         field_kwargs = dict(choices=coupon_code_choices, required=False)
         field_kwargs["help_text"] = _("Define the required coupon for this campaign.")
         field_kwargs["label"] = _("Coupon")

{"golden_diff": "diff --git a/shuup/campaigns/admin_module/forms/_basket.py b/shuup/campaigns/admin_module/forms/_basket.py\n--- a/shuup/campaigns/admin_module/forms/_basket.py\n+++ b/shuup/campaigns/admin_module/forms/_basket.py\n@@ -30,7 +30,7 @@\n         if supplier:\n             coupons = coupons.filter(supplier=supplier)\n \n-        coupon_code_choices = [('', '')] + list(coupons.values_list(\"pk\", \"code\"))\n+        coupon_code_choices = [('', '---------')] + list(coupons.values_list(\"pk\", \"code\"))\n         field_kwargs = dict(choices=coupon_code_choices, required=False)\n         field_kwargs[\"help_text\"] = _(\"Define the required coupon for this campaign.\")\n         field_kwargs[\"label\"] = _(\"Coupon\")\n", "issue": "Xtheme: there is no warning for usaved changes when switching between plugins\nTo reproduce:\r\n1. Edit some content in Xtheme editor\r\n2. Select another plugin without saving\r\n3. See your changes to disappear\r\n\r\nThere probably should be warning before switching plugins when you have unsaved information.\n", "before_files": [{"content": "# This file is part of Shuup.\n#\n# Copyright (c) 2012-2019, Shoop Commerce Ltd. All rights reserved.\n#\n# This source code is licensed under the OSL-3.0 license found in the\n# LICENSE file in the root directory of this source tree.\nfrom django import forms\nfrom django.db.models import Q\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom shuup.admin.shop_provider import get_shop\nfrom shuup.admin.supplier_provider import get_supplier\nfrom shuup.campaigns.models import BasketCampaign, Coupon\n\nfrom ._base import BaseCampaignForm, QuickAddCouponSelect\n\n\nclass BasketCampaignForm(BaseCampaignForm):\n    class Meta(BaseCampaignForm.Meta):\n        model = BasketCampaign\n\n    def __init__(self, *args, **kwargs):\n        super(BasketCampaignForm, self).__init__(*args, **kwargs)\n\n        coupons = Coupon.objects.filter(\n            Q(active=True, shop=get_shop(self.request)),\n            Q(campaign=None) | Q(campaign=self.instance),\n        )\n        supplier = get_supplier(self.request)\n        if supplier:\n            coupons = coupons.filter(supplier=supplier)\n\n        coupon_code_choices = [('', '')] + list(coupons.values_list(\"pk\", \"code\"))\n        field_kwargs = dict(choices=coupon_code_choices, required=False)\n        field_kwargs[\"help_text\"] = _(\"Define the required coupon for this campaign.\")\n        field_kwargs[\"label\"] = _(\"Coupon\")\n        field_kwargs[\"widget\"] = QuickAddCouponSelect(editable_model=\"campaigns.Coupon\")\n        if self.instance.pk and self.instance.coupon:\n            field_kwargs[\"initial\"] = self.instance.coupon.pk\n\n        self.fields[\"coupon\"] = forms.ChoiceField(**field_kwargs)\n\n        # the supplier will be, by default, the current one\n        if supplier:\n            self.fields[\"supplier\"].widget = forms.HiddenInput()\n\n    def clean_coupon(self):\n        coupon = self.cleaned_data.get(\"coupon\")\n        if coupon:\n            coupon = Coupon.objects.get(pk=coupon)\n        return coupon or None\n\n    def clean_supplier(self):\n        return self.cleaned_data.get(\"supplier\") or get_supplier(self.request)\n", "path": "shuup/campaigns/admin_module/forms/_basket.py"}], "after_files": [{"content": "# This file is part of Shuup.\n#\n# Copyright (c) 2012-2019, Shoop Commerce Ltd. All rights reserved.\n#\n# This source code is licensed under the OSL-3.0 license found in the\n# LICENSE file in the root directory of this source tree.\nfrom django import forms\nfrom django.db.models import Q\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom shuup.admin.shop_provider import get_shop\nfrom shuup.admin.supplier_provider import get_supplier\nfrom shuup.campaigns.models import BasketCampaign, Coupon\n\nfrom ._base import BaseCampaignForm, QuickAddCouponSelect\n\n\nclass BasketCampaignForm(BaseCampaignForm):\n    class Meta(BaseCampaignForm.Meta):\n        model = BasketCampaign\n\n    def __init__(self, *args, **kwargs):\n        super(BasketCampaignForm, self).__init__(*args, **kwargs)\n\n        coupons = Coupon.objects.filter(\n            Q(active=True, shop=get_shop(self.request)),\n            Q(campaign=None) | Q(campaign=self.instance),\n        )\n        supplier = get_supplier(self.request)\n        if supplier:\n            coupons = coupons.filter(supplier=supplier)\n\n        coupon_code_choices = [('', '---------')] + list(coupons.values_list(\"pk\", \"code\"))\n        field_kwargs = dict(choices=coupon_code_choices, required=False)\n        field_kwargs[\"help_text\"] = _(\"Define the required coupon for this campaign.\")\n        field_kwargs[\"label\"] = _(\"Coupon\")\n        field_kwargs[\"widget\"] = QuickAddCouponSelect(editable_model=\"campaigns.Coupon\")\n        if self.instance.pk and self.instance.coupon:\n            field_kwargs[\"initial\"] = self.instance.coupon.pk\n\n        self.fields[\"coupon\"] = forms.ChoiceField(**field_kwargs)\n\n        # the supplier will be, by default, the current one\n        if supplier:\n            self.fields[\"supplier\"].widget = forms.HiddenInput()\n\n    def clean_coupon(self):\n        coupon = self.cleaned_data.get(\"coupon\")\n        if coupon:\n            coupon = Coupon.objects.get(pk=coupon)\n        return coupon or None\n\n    def clean_supplier(self):\n        return self.cleaned_data.get(\"supplier\") or get_supplier(self.request)\n", "path": "shuup/campaigns/admin_module/forms/_basket.py"}]}