From e70cf31d0f6302cc1d99d4c872683f7c96b6c5c8 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 14 Jan 2025 11:14:21 +0100 Subject: [PATCH] Addons: allow to set a "Default" or a explicit position for flyout (#11891) - Add a new `flyout_position` field to the `AddonsConfig` model - Show the field in the form - Return the field in the APIv3 to be consumed by the frontend ---- * Related https://github.com/readthedocs/addons/issues/434 --- readthedocs/projects/constants.py | 12 +++++++ readthedocs/projects/forms.py | 1 + .../migrations/0143_addons_flyout_position.py | 35 +++++++++++++++++++ readthedocs/projects/models.py | 15 +++++++- readthedocs/proxito/tests/responses/v1.json | 3 +- readthedocs/proxito/views/hosting.py | 1 + 6 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 readthedocs/projects/migrations/0143_addons_flyout_position.py diff --git a/readthedocs/projects/constants.py b/readthedocs/projects/constants.py index 08db597e053..b43d5aa48c0 100644 --- a/readthedocs/projects/constants.py +++ b/readthedocs/projects/constants.py @@ -443,3 +443,15 @@ (ADDONS_FLYOUT_SORTING_CALVER, _("CalVer (YYYY.0M.0M)")), (ADDONS_FLYOUT_SORTING_CUSTOM_PATTERN, _("Define your own pattern")), ) + +ADDONS_FLYOUT_POSITION_BOTTOM_LEFT = "bottom-left" +ADDONS_FLYOUT_POSITION_BOTTOM_RIGHT = "bottom-right" +ADDONS_FLYOUT_POSITION_TOP_LEFT = "top-left" +ADDONS_FLYOUT_POSITION_TOP_RIGHT = "top-right" +ADDONS_FLYOUT_POSITION_CHOICES = ( + (None, _("Default (from theme or Read the Docs)")), + (ADDONS_FLYOUT_POSITION_BOTTOM_LEFT, _("Bottom left")), + (ADDONS_FLYOUT_POSITION_BOTTOM_RIGHT, _("Bottom right")), + (ADDONS_FLYOUT_POSITION_TOP_LEFT, _("Top left")), + (ADDONS_FLYOUT_POSITION_TOP_RIGHT, _("Top right")), +) diff --git a/readthedocs/projects/forms.py b/readthedocs/projects/forms.py index af64c52861d..d8635c28f8d 100644 --- a/readthedocs/projects/forms.py +++ b/readthedocs/projects/forms.py @@ -657,6 +657,7 @@ class Meta: "flyout_sorting", "flyout_sorting_latest_stable_at_beginning", "flyout_sorting_custom_pattern", + "flyout_position", "hotkeys_enabled", "search_enabled", "linkpreviews_enabled", diff --git a/readthedocs/projects/migrations/0143_addons_flyout_position.py b/readthedocs/projects/migrations/0143_addons_flyout_position.py new file mode 100644 index 00000000000..a6b824871fc --- /dev/null +++ b/readthedocs/projects/migrations/0143_addons_flyout_position.py @@ -0,0 +1,35 @@ +# Generated by Django 4.2.17 on 2025-01-08 11:15 + +from django.db import migrations, models +from django_safemigrate import Safe + + +class Migration(migrations.Migration): + safe = Safe.before_deploy + + dependencies = [ + ('projects', '0142_update_dj_simple_history'), + ] + + operations = [ + migrations.AlterField( + model_name='addonsconfig', + name='flyout_enabled', + field=models.BooleanField(default=True, verbose_name='Enabled'), + ), + migrations.AddField( + model_name='addonsconfig', + name='flyout_position', + field=models.CharField(blank=True, choices=[(None, 'Default (from theme or Read the Docs)'), ('bottom-left', 'Bottom left'), ('bottom-right', 'Bottom right'), ('top-left', 'Top left'), ('top-right', 'Top right')], default=None, max_length=64, null=True, verbose_name='Position'), + ), + migrations.AlterField( + model_name='historicaladdonsconfig', + name='flyout_enabled', + field=models.BooleanField(default=True, verbose_name='Enabled'), + ), + migrations.AddField( + model_name='historicaladdonsconfig', + name='flyout_position', + field=models.CharField(blank=True, choices=[(None, 'Default (from theme or Read the Docs)'), ('bottom-left', 'Bottom left'), ('bottom-right', 'Bottom right'), ('top-left', 'Top left'), ('top-right', 'Top right')], default=None, max_length=64, null=True, verbose_name='Position'), + ), + ] diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index d21d94aa000..84a20e698a3 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -61,6 +61,7 @@ from readthedocs.vcs_support.backends import backend_cls from .constants import ( + ADDONS_FLYOUT_POSITION_CHOICES, ADDONS_FLYOUT_SORTING_CHOICES, ADDONS_FLYOUT_SORTING_SEMVER_READTHEDOCS_COMPATIBLE, DOWNLOADABLE_MEDIA_TYPES, @@ -194,7 +195,10 @@ class AddonsConfig(TimeStampedModel): filetreediff_enabled = models.BooleanField(default=False, null=True, blank=True) # Flyout - flyout_enabled = models.BooleanField(default=True) + flyout_enabled = models.BooleanField( + default=True, + verbose_name=_("Enabled"), + ) flyout_sorting = models.CharField( verbose_name=_("Sorting of versions"), choices=ADDONS_FLYOUT_SORTING_CHOICES, @@ -217,6 +221,15 @@ class AddonsConfig(TimeStampedModel): default=True, ) + flyout_position = models.CharField( + choices=ADDONS_FLYOUT_POSITION_CHOICES, + max_length=64, + default=None, # ``None`` means use the default (theme override if present or Read the Docs default) + null=True, + blank=True, + verbose_name=_("Position"), + ) + # Hotkeys hotkeys_enabled = models.BooleanField(default=True) diff --git a/readthedocs/proxito/tests/responses/v1.json b/readthedocs/proxito/tests/responses/v1.json index ccfb8e2696d..c507fc314d3 100644 --- a/readthedocs/proxito/tests/responses/v1.json +++ b/readthedocs/proxito/tests/responses/v1.json @@ -155,7 +155,8 @@ "enabled": false }, "flyout": { - "enabled": true + "enabled": true, + "position": null }, "search": { "enabled": true, diff --git a/readthedocs/proxito/views/hosting.py b/readthedocs/proxito/views/hosting.py index 3299419c991..408a09d1ae3 100644 --- a/readthedocs/proxito/views/hosting.py +++ b/readthedocs/proxito/views/hosting.py @@ -493,6 +493,7 @@ def _v1(self, project, version, build, filename, url, request): # "branch": version.identifier if version else None, # "filepath": "/docs/index.rst", # }, + "position": project.addons.flyout_position, }, "customscript": { "enabled": project.addons.customscript_enabled,