rudimentary theme support
This commit is contained in:
parent
b44197a1c5
commit
9399e5c377
23 changed files with 925 additions and 307 deletions
|
@ -9,10 +9,10 @@ from django.conf import settings
|
|||
from django.core.cache import cache
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.db.models import Q
|
||||
from django.db.models import Q, Prefetch
|
||||
from django.forms import (BooleanField, CharField, ChoiceField, DecimalField, Form, JSONField, ModelChoiceField,
|
||||
ModelForm, MultipleChoiceField, Select, ValidationError)
|
||||
from django.forms.widgets import HiddenInput
|
||||
from django.forms.widgets import HiddenInput, TextInput
|
||||
from django.utils.translation import get_language
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from shapely.geometry.geo import mapping
|
||||
|
@ -21,8 +21,10 @@ from pydantic import ValidationError as PydanticValidationError
|
|||
from c3nav.editor.models import ChangeSet, ChangeSetUpdate
|
||||
from c3nav.mapdata.fields import GeometryField
|
||||
from c3nav.mapdata.forms import I18nModelFormMixin
|
||||
from c3nav.mapdata.models import GraphEdge
|
||||
from c3nav.mapdata.models import GraphEdge, LocationGroup
|
||||
from c3nav.mapdata.models.access import AccessPermission
|
||||
from c3nav.mapdata.models.geometry.space import ObstacleGroup
|
||||
from c3nav.mapdata.models.theme import ThemeLocationGroupBackgroundColor, ThemeObstacleGroupBackgroundColor
|
||||
from c3nav.routing.schemas import LocateRequestPeerSchema
|
||||
|
||||
|
||||
|
@ -32,6 +34,69 @@ class EditorFormBase(I18nModelFormMixin, ModelForm):
|
|||
super().__init__(*args, **kwargs)
|
||||
creating = not self.instance.pk
|
||||
|
||||
if self._meta.model.__name__ == 'Theme':
|
||||
if creating:
|
||||
locationgroup_theme_colors = {}
|
||||
obstaclegroup_theme_colors = {}
|
||||
else:
|
||||
locationgroup_theme_colors = {
|
||||
l.location_group_id: l
|
||||
for l in self.instance.location_groups.filter(theme_id=self.instance.pk)
|
||||
}
|
||||
obstaclegroup_theme_colors = {
|
||||
o.obstacle_group_id: o
|
||||
for o in self.instance.obstacle_groups.filter(theme_id=self.instance.pk)
|
||||
}
|
||||
|
||||
# TODO: can we get the model class via relationships?
|
||||
for locationgroup in LocationGroup.objects.prefetch_related(
|
||||
Prefetch('theme_colors', ThemeLocationGroupBackgroundColor.objects.only('fill_color'))).all():
|
||||
related = locationgroup_theme_colors.get(locationgroup.pk, None)
|
||||
value = related.fill_color if related is not None else None
|
||||
other_themes_colors = {
|
||||
l.title: l.fill_color
|
||||
for l in locationgroup.theme_colors.all()
|
||||
if related is None or l.pk != related.pk
|
||||
}
|
||||
if len(other_themes_colors) > 0:
|
||||
other_themes_colors = json.dumps(other_themes_colors)
|
||||
else:
|
||||
other_themes_colors = False
|
||||
field = CharField(max_length=32,
|
||||
label=locationgroup.title,
|
||||
required=False,
|
||||
initial=value,
|
||||
widget=TextInput(attrs={
|
||||
'data-themed-color': True,
|
||||
'data-color-base-theme': locationgroup.color if locationgroup.color else False,
|
||||
'data-colors-other-themes': other_themes_colors,
|
||||
}))
|
||||
self.fields[f'locationgroup_{locationgroup.pk}'] = field
|
||||
|
||||
for obstaclegroup in ObstacleGroup.objects.prefetch_related(
|
||||
Prefetch('theme_colors', ThemeObstacleGroupBackgroundColor.objects.only('fill_color'))).all():
|
||||
related = obstaclegroup_theme_colors.get(obstaclegroup.pk, None)
|
||||
value = related.fill_color if related is not None else None
|
||||
other_themes_colors = {
|
||||
o.title: o.fill_color
|
||||
for o in obstaclegroup.theme_colors.all()
|
||||
if related is None or o.pk != related.pk
|
||||
}
|
||||
if len(other_themes_colors) > 0:
|
||||
other_themes_colors = json.dumps(other_themes_colors)
|
||||
else:
|
||||
other_themes_colors = False
|
||||
field = CharField(max_length=32,
|
||||
label=obstaclegroup.title,
|
||||
required=False,
|
||||
initial=value,
|
||||
widget=TextInput(attrs={
|
||||
'data-themed-color': True,
|
||||
'data-color-base-theme': obstaclegroup.color if obstaclegroup.color else False,
|
||||
'data-colors-other-themes': other_themes_colors,
|
||||
}))
|
||||
self.fields[f'obstaclegroup_{obstaclegroup.pk}'] = field
|
||||
|
||||
if hasattr(self.instance, 'author_id'):
|
||||
if self.instance.author_id is None:
|
||||
self.instance.author = request.user
|
||||
|
@ -309,6 +374,35 @@ class EditorFormBase(I18nModelFormMixin, ModelForm):
|
|||
groups = tuple((int(val) if val.isdigit() else val) for val in groups)
|
||||
self.instance.groups.set(groups)
|
||||
|
||||
if self._meta.model.__name__ == 'Theme':
|
||||
locationgroup_colors = {l.location_group_id: l for l in self.instance.location_groups.all()}
|
||||
for locationgroup in LocationGroup.objects.all():
|
||||
value = self.cleaned_data[f'locationgroup_{locationgroup.pk}']
|
||||
if value:
|
||||
color = locationgroup_colors.get(locationgroup.pk,
|
||||
ThemeLocationGroupBackgroundColor(theme=self.instance,
|
||||
location_group=locationgroup))
|
||||
color.fill_color = value
|
||||
color.save()
|
||||
else:
|
||||
color = locationgroup_colors.get(locationgroup.pk, None)
|
||||
if color is not None:
|
||||
color.delete()
|
||||
|
||||
obstaclegroup_colors = {o.obstacle_group_id: o for o in self.instance.obstacle_groups.all()}
|
||||
for obstaclegroup in ObstacleGroup.objects.all():
|
||||
value = self.cleaned_data[f'obstaclegroup_{obstaclegroup.pk}']
|
||||
if value:
|
||||
color = obstaclegroup_colors.get(obstaclegroup.pk,
|
||||
ThemeObstacleGroupBackgroundColor(theme=self.instance,
|
||||
obstacle_group=obstaclegroup))
|
||||
color.fill_color = value
|
||||
color.save()
|
||||
else:
|
||||
color = obstaclegroup_colors.get(obstaclegroup.pk)
|
||||
if color is not None:
|
||||
color.delete()
|
||||
|
||||
|
||||
def create_editor_form(editor_model):
|
||||
possible_fields = ['slug', 'name', 'title', 'title_plural', 'help_text', 'position_secret',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue