external_url_label and external_url for locationgroup as well
This commit is contained in:
parent
9aab30611c
commit
48cb444691
6 changed files with 63 additions and 11 deletions
|
@ -399,8 +399,8 @@ class EditorFormBase(I18nModelFormMixin, ModelForm):
|
||||||
def create_editor_form(editor_model):
|
def create_editor_form(editor_model):
|
||||||
possible_fields = [
|
possible_fields = [
|
||||||
'slug', 'name', 'title', 'title_plural', 'help_text', 'position_secret', 'icon', 'join_edges',
|
'slug', 'name', 'title', 'title_plural', 'help_text', 'position_secret', 'icon', 'join_edges',
|
||||||
'up_separate', 'bssid', 'main_point', 'external_url', 'hub_import_type', 'walk', 'ordering',
|
'up_separate', 'bssid', 'main_point', 'external_url', 'external_url_label', 'hub_import_type', 'walk',
|
||||||
'category', 'width', 'groups', 'height', 'color', 'in_legend', 'priority', 'hierarchy', 'icon_name',
|
'ordering', 'category', 'width', 'groups', 'height', 'color', 'in_legend', 'priority', 'hierarchy', 'icon_name',
|
||||||
'base_altitude', 'intermediate', 'waytype', 'access_restriction', 'default_height', 'door_height', 'outside',
|
'base_altitude', 'intermediate', 'waytype', 'access_restriction', 'default_height', 'door_height', 'outside',
|
||||||
'can_search', 'can_describe', 'geometry', 'single', 'altitude', 'level_index', 'short_label',
|
'can_search', 'can_describe', 'geometry', 'single', 'altitude', 'level_index', 'short_label',
|
||||||
'origin_space', 'target_space', 'data',
|
'origin_space', 'target_space', 'data',
|
||||||
|
@ -418,7 +418,7 @@ def create_editor_form(editor_model):
|
||||||
'color_background', 'color_wall_fill', 'color_wall_border', 'color_door_fill', 'color_ground_fill',
|
'color_background', 'color_wall_fill', 'color_wall_border', 'color_door_fill', 'color_ground_fill',
|
||||||
'color_obstacles_default_fill', 'color_obstacles_default_border', 'stroke_color', 'stroke_width',
|
'color_obstacles_default_fill', 'color_obstacles_default_border', 'stroke_color', 'stroke_width',
|
||||||
'stroke_opacity', 'fill_color', 'fill_opacity', 'interactive', 'point_icon', 'extra_data', 'show_label',
|
'stroke_opacity', 'fill_color', 'fill_opacity', 'interactive', 'point_icon', 'extra_data', 'show_label',
|
||||||
'show_geometry', 'external_url', 'show_label', 'show_geometry', 'external_url', 'default_geomtype',
|
'show_geometry', 'show_label', 'show_geometry', 'default_geomtype',
|
||||||
]
|
]
|
||||||
field_names = [field.name for field in editor_model._meta.get_fields()
|
field_names = [field.name for field in editor_model._meta.get_fields()
|
||||||
if not field.one_to_many and not isinstance(field, ManyToManyRel)]
|
if not field.one_to_many and not isinstance(field, ManyToManyRel)]
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Generated by Django 5.0.8 on 2024-12-19 10:55
|
||||||
|
|
||||||
|
import c3nav.mapdata.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mapdata', '0121_level_level_index_alter_level_short_label'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='locationgroup',
|
||||||
|
name='external_url',
|
||||||
|
field=models.URLField(blank=True, null=True, verbose_name='external URL'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='locationgroup',
|
||||||
|
name='external_url_label',
|
||||||
|
field=c3nav.mapdata.fields.I18nField(blank=True, fallback_any=True, fallback_value='', plural_name='external_url_labels', verbose_name='external URL label'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -105,6 +105,7 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
||||||
can_search = models.BooleanField(default=True, verbose_name=_('can be searched'))
|
can_search = models.BooleanField(default=True, verbose_name=_('can be searched'))
|
||||||
can_describe = models.BooleanField(default=True, verbose_name=_('can describe'))
|
can_describe = models.BooleanField(default=True, verbose_name=_('can describe'))
|
||||||
icon = models.CharField(_('icon'), max_length=32, null=True, blank=True, help_text=_('any material icons name'))
|
icon = models.CharField(_('icon'), max_length=32, null=True, blank=True, help_text=_('any material icons name'))
|
||||||
|
external_url = models.URLField(_('external URL'), null=True, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
@ -123,6 +124,12 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
||||||
(_('can describe'), _('Yes') if self.can_describe else _('No')),
|
(_('can describe'), _('Yes') if self.can_describe else _('No')),
|
||||||
(_('icon'), self.effective_icon),
|
(_('icon'), self.effective_icon),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
if self.external_url:
|
||||||
|
result['external_url'] = {
|
||||||
|
'title': self.external_url_label or _('Open external URL'),
|
||||||
|
'url': self.external_url,
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -158,13 +165,16 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
||||||
def effective_icon(self):
|
def effective_icon(self):
|
||||||
return self.icon or None
|
return self.icon or None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def external_url_label(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class SpecificLocation(Location, models.Model):
|
class SpecificLocation(Location, models.Model):
|
||||||
groups = models.ManyToManyField('mapdata.LocationGroup', verbose_name=_('Location Groups'), blank=True)
|
groups = models.ManyToManyField('mapdata.LocationGroup', verbose_name=_('Location Groups'), blank=True)
|
||||||
label_settings = models.ForeignKey('mapdata.LabelSettings', null=True, blank=True, on_delete=models.PROTECT,
|
label_settings = models.ForeignKey('mapdata.LabelSettings', null=True, blank=True, on_delete=models.PROTECT,
|
||||||
verbose_name=_('label settings'))
|
verbose_name=_('label settings'))
|
||||||
label_override = I18nField(_('Label override'), plural_name='label_overrides', blank=True, fallback_any=True)
|
label_override = I18nField(_('Label override'), plural_name='label_overrides', blank=True, fallback_any=True)
|
||||||
external_url = models.URLField(_('external URL'), null=True, blank=True)
|
|
||||||
import_block_data = models.BooleanField(_('don\'t change metadata on import'), default=False)
|
import_block_data = models.BooleanField(_('don\'t change metadata on import'), default=False)
|
||||||
import_block_geom = models.BooleanField(_('don\'t change geometry on import'), default=False)
|
import_block_geom = models.BooleanField(_('don\'t change geometry on import'), default=False)
|
||||||
|
|
||||||
|
@ -214,12 +224,6 @@ class SpecificLocation(Location, models.Model):
|
||||||
} for group in sorted(groups, key=attrgetter('priority'), reverse=True))
|
} for group in sorted(groups, key=attrgetter('priority'), reverse=True))
|
||||||
))
|
))
|
||||||
|
|
||||||
if self.external_url:
|
|
||||||
result['display'].insert(3, (_('External URL'), {
|
|
||||||
'title': _('Open'),
|
|
||||||
'url': self.external_url,
|
|
||||||
}))
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
|
@ -252,6 +256,13 @@ class SpecificLocation(Location, models.Model):
|
||||||
return group.icon
|
return group.icon
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def external_url_label(self):
|
||||||
|
for group in self.groups.all():
|
||||||
|
if group.icon and getattr(group.category, 'allow_' + self.__class__._meta.default_related_name):
|
||||||
|
return group.external_url_label
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class LocationGroupCategory(SerializableMixin, models.Model):
|
class LocationGroupCategory(SerializableMixin, models.Model):
|
||||||
name = models.SlugField(_('Name'), unique=True, max_length=50)
|
name = models.SlugField(_('Name'), unique=True, max_length=50)
|
||||||
|
@ -343,6 +354,8 @@ class LocationGroup(Location, models.Model):
|
||||||
hub_import_type = models.CharField(max_length=100, verbose_name=_('hub import type'), null=True, blank=True,
|
hub_import_type = models.CharField(max_length=100, verbose_name=_('hub import type'), null=True, blank=True,
|
||||||
unique=True,
|
unique=True,
|
||||||
help_text=_('assign this group to imported hub locations of this type'))
|
help_text=_('assign this group to imported hub locations of this type'))
|
||||||
|
external_url_label = I18nField(_('external URL label'), plural_name='external_url_labels', blank=True,
|
||||||
|
fallback_any=True, fallback_value="")
|
||||||
|
|
||||||
objects = LocationGroupManager()
|
objects = LocationGroupManager()
|
||||||
|
|
||||||
|
|
|
@ -835,6 +835,7 @@ class LocationDisplay(BaseSchema):
|
||||||
description="space",
|
description="space",
|
||||||
example=3,
|
example=3,
|
||||||
)
|
)
|
||||||
|
external_url: Optional[DisplayURL] = None
|
||||||
display: list[
|
display: list[
|
||||||
tuple[
|
tuple[
|
||||||
Annotated[NonEmptyStr, APIField(title="field title")],
|
Annotated[NonEmptyStr, APIField(title="field title")],
|
||||||
|
|
|
@ -437,6 +437,7 @@ c3nav = {
|
||||||
$location_details.find('.details-body').html('');
|
$location_details.find('.details-body').html('');
|
||||||
$location_details.find('.editor').hide();
|
$location_details.find('.editor').hide();
|
||||||
$location_details.find('.report').hide();
|
$location_details.find('.report').hide();
|
||||||
|
$location_details.find('.external-url-button').hide();
|
||||||
$location_details.removeClass('loading');
|
$location_details.removeClass('loading');
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -494,6 +495,13 @@ c3nav = {
|
||||||
$location_details.find('.report').hide();
|
$location_details.find('.report').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.external_url) {
|
||||||
|
$location_details.find('.external-url-button a').attr('href', data.external_url.url);
|
||||||
|
$location_details.find('.external-url-button span').text(data.external_url.title);
|
||||||
|
} else {
|
||||||
|
$location_details.find('.external-url-button').hide();
|
||||||
|
}
|
||||||
|
|
||||||
if (data.geometry && data.level) {
|
if (data.geometry && data.level) {
|
||||||
L.geoJSON(data.geometry, {
|
L.geoJSON(data.geometry, {
|
||||||
style: {
|
style: {
|
||||||
|
|
|
@ -184,6 +184,12 @@
|
||||||
<button class="button close button-clear material-symbols float-right">close</button>
|
<button class="button close button-clear material-symbols float-right">close</button>
|
||||||
<h2>{% trans 'Details' %}</h2>
|
<h2>{% trans 'Details' %}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="details-buttons buttons external-url-button">
|
||||||
|
<a class="button button-clear external-url" target="_blank">
|
||||||
|
<i class="material-symbols">open_in_new</i>
|
||||||
|
<span></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<div class="details-body"></div>
|
<div class="details-body"></div>
|
||||||
<div class="details-buttons buttons">
|
<div class="details-buttons buttons">
|
||||||
<a class="button button-clear report report-issue">
|
<a class="button button-clear report report-issue">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue