wip: display templates in importer by origin (me/staff/community)

Co-authored-by: David Larlet <david@larlet.fr>
This commit is contained in:
Yohan Boniface 2025-04-18 18:01:54 +02:00
parent 23f7337a98
commit 71c6974c3c
6 changed files with 85 additions and 45 deletions

View file

@ -9,6 +9,13 @@ class PublicManager(models.Manager):
.filter(share_status=self.model.PUBLIC)
)
def starred_by_staff(self):
from .models import Star, User
staff = User.objects.filter(is_staff=True)
stars = Star.objects.filter(by__in=staff).values("map")
return self.get_queryset().filter(pk__in=stars)
class PrivateQuerySet(models.QuerySet):
def for_user(self, user):

View file

@ -4,7 +4,7 @@
margin-top: 100px;
width: var(--dialog-width);
max-width: 100vw;
max-height: 50vh;
max-height: 80vh;
padding: 20px;
border: 1px solid #222;
background-color: var(--background-color);
@ -12,11 +12,14 @@
border-radius: 5px;
overflow-y: auto;
height: fit-content;
max-height: 90vh;
}
.umap-dialog ul + h4 {
margin-top: var(--box-margin);
}
.umap-dialog .body {
max-height: 50vh;
overflow-y: auto;
}
:where([data-component="no-dialog"]:not([hidden])) {
display: block;
position: relative;

View file

@ -725,7 +725,7 @@ Fields.IconUrl = class extends Fields.BlurInput {
<button class="flat tab-url" data-ref=url>${translate('URL')}</button>
</div>
`)
this.tabs.appendChild(root)
;[recent, symbols, chars, url].forEach((node) => this.tabs.appendChild(node))
if (Icon.RECENT.length) {
recent.addEventListener('click', (event) => {
event.stopPropagation()

View file

@ -4,27 +4,23 @@ import { BaseAjax, SingleMixin } from '../autocomplete.js'
import { translate } from '../i18n.js'
import * as Utils from '../utils.js'
const BOUNDARY_TYPES = {
admin_6: 'département',
admin_7: 'pays (loi Voynet)',
admin_8: 'commune',
admin_9: 'quartier, hameau, arrondissement',
political: 'canton',
local_authority: 'EPCI',
}
const TEMPLATE = `
<h3>${translate('Load template')}</h3>
<p>${translate('GeoDataMine: thematic data from OpenStreetMap')}.</p>
<div>
<h3>${translate('Load map template')}</h3>
<p>${translate('Use a template to initialize your map')}.</p>
<div class="formbox">
<select name="theme">
<option value="">${translate('Choose a template')}</option>
</select>
<div class="flat-tabs" data-ref="tabs">
<button type="button" class="flat" data-value="mine" data-ref="mine">${translate('My templates')}</button>
<button type="button" class="flat" data-value="staff">${translate('Staff templates')}</button>
<button type="button" class="flat" data-value="community">${translate('Community templates')}</button>
</div>
<div data-ref="body" class="body"></div>
<label>
<input type="checkbox" name="include_data" />
${translate('Include template data, if any')}
</label>
</div>
</div>
`
export class Importer {
@ -35,28 +31,50 @@ export class Importer {
}
async open(importer) {
const container = DomUtil.create('div')
container.innerHTML = TEMPLATE
const select = container.querySelector('select')
const [root, { tabs, include_data, body, mine }] =
Utils.loadTemplateWithRefs(TEMPLATE)
const uri = this.umap.urls.get('template_list')
const [data, response, error] = await this.umap.server.get(uri)
const userIsAuth = Boolean(this.umap.properties.user?.id)
const defaultTab = userIsAuth ? 'mine' : 'staff'
mine.hidden = !userIsAuth
const loadTemplates = async (source) => {
const [data, response, error] = await this.umap.server.get(
`${uri}?source=${source}`
)
if (!error) {
body.innerHTML = ''
for (const template of data.templates) {
DomUtil.element({
tagName: 'option',
value: template.id,
textContent: template.name,
parent: select,
})
const item = Utils.loadTemplate(
`<dl>
<dt><label><input type="radio" value="${template.id}" name="template" />${template.name}</label></dt>
<dd>${template.description}</dd>
</dl>`
)
body.appendChild(item)
}
tabs.querySelectorAll('button').forEach((el) => el.classList.remove('on'))
tabs.querySelector(`[data-value="${source}"]`).classList.add('on')
} else {
console.error(response)
}
}
loadTemplates(defaultTab)
tabs
.querySelectorAll('button')
.forEach((el) =>
el.addEventListener('click', () => loadTemplates(el.dataset.value))
)
const confirm = (form) => {
console.log(form)
if (!form.template) {
Alert.error(translate('You must select a template.'))
return false
}
let url = this.umap.urls.get('map_download', {
map_id: select.options[select.selectedIndex].value,
map_id: form.template,
})
if (!container.querySelector('[name=include_data]').checked) {
if (!form.include_data) {
url = `${url}?include_data=0`
}
importer.url = url
@ -67,7 +85,7 @@ export class Importer {
importer.dialog
.open({
template: container,
template: root,
className: `${this.id} importer dark`,
accept: translate('Use this template'),
cancel: false,

View file

@ -301,6 +301,15 @@
</form>
</fieldset>
</details>
<details open>
<summary>With tabs</summary>
<div class="flat-tabs" data-ref="tabs">
<button class="flat on" data-ref="recent">Récents</button>
<button class="flat" data-ref="symbols">Symbole</button>
<button class="flat" data-ref="chars">Emoji &amp; texte</button>
<button class="flat" data-ref="url">URL</button>
</div>
</details>
</div>
<h4>Importers</h4>
<div class="umap-dialog window importers dark">

View file

@ -138,9 +138,7 @@ class PublicMapsMixin(object):
return maps
def get_highlighted_maps(self):
staff = User.objects.filter(is_staff=True)
stars = Star.objects.filter(by__in=staff).values("map")
qs = Map.public.filter(pk__in=stars)
qs = Map.public.starred_by_staff()
maps = qs.order_by("-modified_at")
return maps
@ -1459,9 +1457,14 @@ class TemplateList(ListView):
model = Map
def render_to_response(self, context, **response_kwargs):
if self.request.user.is_authenticated:
source = self.request.GET.get("source")
if source == "mine":
qs = Map.private.filter(is_template=True).for_user(self.request.user)
else:
elif source == "community":
qs = Map.public.filter(is_template=True)
templates = [{"id": m.id, "name": m.name} for m in qs]
elif source == "staff":
qs = Map.public.starred_by_staff().filter(is_template=True)
templates = [
{"id": m.id, "name": m.name, "description": m.description} for m in qs
]
return simple_json_response(templates=templates)