feat: Implemented single and multiselect autocomplete
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
from functools import wraps
|
||||
from dal import autocomplete
|
||||
|
||||
from config_models.admin import ConfigurationModelAdmin
|
||||
from django import forms
|
||||
@@ -16,7 +17,7 @@ from django.contrib.auth.forms import UserChangeForm as BaseUserChangeForm
|
||||
from django.db import models, router, transaction
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.http.request import QueryDict
|
||||
from django.urls import reverse
|
||||
from django.urls import reverse, path
|
||||
from django.utils.translation import ngettext
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from opaque_keys import InvalidKeyError
|
||||
@@ -45,6 +46,7 @@ from common.djangoapps.student.models import (
|
||||
UserProfile,
|
||||
UserTestGroup
|
||||
)
|
||||
from common.djangoapps.student.constants import LANGUAGE_CHOICES
|
||||
from common.djangoapps.student.roles import REGISTERED_ACCESS_ROLES
|
||||
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
@@ -309,9 +311,25 @@ class CourseEnrollmentAdmin(DisableEnrollmentAdminMixin, admin.ModelAdmin):
|
||||
return super().get_queryset(request).select_related('user') # lint-amnesty, pylint: disable=no-member, super-with-arguments
|
||||
|
||||
|
||||
class LanguageAutocomplete(autocomplete.Select2ListView):
|
||||
def get_list(self):
|
||||
return [lang for lang in LANGUAGE_CHOICES if self.q.lower() in lang.lower()]
|
||||
|
||||
class UserProfileInlineForm(forms.ModelForm):
|
||||
language = forms.CharField(
|
||||
required=False,
|
||||
widget=autocomplete.ListSelect2(url='admin:language-autocomplete')
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class UserProfileInline(admin.StackedInline):
|
||||
""" Inline admin interface for UserProfile model. """
|
||||
model = UserProfile
|
||||
form = UserProfileInlineForm
|
||||
can_delete = False
|
||||
verbose_name_plural = _('User profile')
|
||||
|
||||
@@ -359,6 +377,17 @@ class UserAdmin(BaseUserAdmin):
|
||||
return django_readonly + ('username',)
|
||||
return django_readonly
|
||||
|
||||
def get_urls(self):
|
||||
urls = super().get_urls()
|
||||
custom_urls = [
|
||||
path(
|
||||
'language-autocomplete/',
|
||||
LanguageAutocomplete.as_view(),
|
||||
name='language-autocomplete'
|
||||
),
|
||||
]
|
||||
return custom_urls + urls
|
||||
|
||||
|
||||
@admin.register(UserAttribute)
|
||||
class UserAttributeAdmin(admin.ModelAdmin):
|
||||
|
||||
3
common/djangoapps/student/constants.py
Normal file
3
common/djangoapps/student/constants.py
Normal file
@@ -0,0 +1,3 @@
|
||||
import pycountry
|
||||
|
||||
LANGUAGE_CHOICES = sorted({lang.name for lang in pycountry.languages if hasattr(lang, 'alpha_2')})
|
||||
@@ -3042,6 +3042,9 @@ INSTALLED_APPS = [
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
|
||||
'dal',
|
||||
'dal_select2',
|
||||
|
||||
# Tweaked version of django.contrib.staticfiles
|
||||
'openedx.core.djangoapps.staticfiles.apps.EdxPlatformStaticFilesConfig',
|
||||
|
||||
|
||||
@@ -1,17 +1,81 @@
|
||||
"""
|
||||
Django admin page for Site Configuration models
|
||||
"""
|
||||
from dal import autocomplete
|
||||
|
||||
|
||||
from django import forms
|
||||
from django.urls import path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.contrib import admin
|
||||
|
||||
from .constants import FEATURE_FLAGS
|
||||
from .models import SiteConfiguration, SiteConfigurationHistory
|
||||
|
||||
class FeatureFlagAutocomplete(autocomplete.Select2ListView):
|
||||
def get_list(self):
|
||||
return list(FEATURE_FLAGS.keys())
|
||||
|
||||
def get_result_label(self, item):
|
||||
return item
|
||||
|
||||
def get_result_value(self, item):
|
||||
return item
|
||||
|
||||
class SiteConfigurationForm(forms.ModelForm):
|
||||
feature_flags = forms.Field(
|
||||
required=False,
|
||||
widget=autocomplete.Select2Multiple(
|
||||
url='admin:feature-flag-autocomplete',
|
||||
attrs={
|
||||
'multiple': 'multiple',
|
||||
'data-tags': 'true',
|
||||
'data-placeholder': 'Select features'
|
||||
}
|
||||
),
|
||||
label="Enabled Features",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SiteConfiguration
|
||||
fields = '__all__'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.fields['site_values'].widget = forms.HiddenInput()
|
||||
current_values = self.instance.site_values or {}
|
||||
selected_labels = []
|
||||
for label, mapping in FEATURE_FLAGS.items():
|
||||
if all(current_values.get(k) == v for k, v in mapping.items()):
|
||||
selected_labels.append(label)
|
||||
|
||||
self.fields['feature_flags'].initial = selected_labels
|
||||
self.fields['feature_flags'].widget.choices = [(v, v) for v in selected_labels]
|
||||
|
||||
|
||||
def clean(self):
|
||||
cleaned = super().clean()
|
||||
|
||||
selected_flags = self.data.getlist('feature_flags')
|
||||
if not isinstance(selected_flags, list):
|
||||
selected_flags = [selected_flags] if selected_flags else []
|
||||
|
||||
site_values = {}
|
||||
for label in selected_flags:
|
||||
site_values.update(FEATURE_FLAGS.get(label, {}))
|
||||
|
||||
cleaned['feature_flags'] = selected_flags
|
||||
cleaned['site_values'] = site_values
|
||||
# self.selected_flags = selected_flags
|
||||
# self.site_values = site_values
|
||||
|
||||
return cleaned
|
||||
|
||||
class SiteConfigurationAdmin(admin.ModelAdmin):
|
||||
"""
|
||||
Admin interface for the SiteConfiguration object.
|
||||
"""
|
||||
form = SiteConfigurationForm
|
||||
list_display = ('site', 'enabled', 'site_values')
|
||||
search_fields = ('site__domain', 'site_values')
|
||||
|
||||
@@ -21,6 +85,17 @@ class SiteConfigurationAdmin(admin.ModelAdmin):
|
||||
"""
|
||||
model = SiteConfiguration
|
||||
|
||||
def get_urls(self):
|
||||
urls = super().get_urls()
|
||||
custom_urls = [
|
||||
path(
|
||||
'feature-flag-autocomplete/',
|
||||
FeatureFlagAutocomplete.as_view(),
|
||||
name='feature-flag-autocomplete'
|
||||
),
|
||||
]
|
||||
return custom_urls + urls
|
||||
|
||||
admin.site.register(SiteConfiguration, SiteConfigurationAdmin)
|
||||
|
||||
|
||||
|
||||
6
openedx/core/djangoapps/site_configuration/constants.py
Normal file
6
openedx/core/djangoapps/site_configuration/constants.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# TODO: Dummy Tags to be replaced by real values
|
||||
FEATURE_FLAGS = {
|
||||
'Forum Notifications': {'enable_forum_notifications': True},
|
||||
'Live Chat': {'enable_live_chat': True},
|
||||
'Dark Mode': {'enable_dark_mode': True},
|
||||
}
|
||||
Reference in New Issue
Block a user