Skip to content

Commit a9f6760

Browse files
committed
WIP ui rework
1 parent fb988fd commit a9f6760

File tree

12 files changed

+342
-159
lines changed

12 files changed

+342
-159
lines changed

geospaas/base_viewer/static/base_viewer/styles.css

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1+
html, body {
2+
width: 100%;
3+
height: 100%;
4+
padding: 0;
5+
margin: 0;
6+
font-family: Arial, sans-serif;
7+
}
8+
9+
.geospaas_app {
10+
height: 100%;
11+
}
12+
13+
.geospaas_selected_tab {
14+
background-color: lightgrey;
15+
}
16+
117
#geospaas_apps {
218
display: grid;
19+
height: 100%;
20+
width: 100%;
321
grid-template-columns: 5% auto;
4-
grid-template-rows: 100%;
22+
grid-template-rows: minmax(0, 1fr);
523
grid-gap: 10px;
624
}
725

@@ -15,6 +33,7 @@
1533
grid-row: 1;
1634
}
1735

18-
.geospaas_selected_tab {
19-
background-color: lightgrey;
20-
}
36+
/* form { display: table; }
37+
p { display: table-row; }
38+
label { display: table-cell; }
39+
input { display: table-cell; } */

geospaas/base_viewer/templates/base_viewer/geospaas.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@
99
<div id="geospaas_sidebar">
1010
{% block geospaas_sidebar %}
1111
{% for app in geospaas_apps %}
12-
<div class="app.label{% if app.label == selected_tab %} geospaas_selected_tab{% endif %}">
12+
<div class="geospaas_tab_label {% if app.label == selected_tab %} geospaas_selected_tab{% endif %}">
1313
<a href="{% url 'base_viewer:index' %}{{ app.path }}">{{ app.label }}</a>
1414
</div>
1515
{% endfor %}
1616
{% endblock geospaas_sidebar %}
1717
</div>
1818
<div id="geospaas_tab_contents">
19-
{% block geospaas_tab_contents %}{% endblock geospaas_tab_contents %}
20-
{% comment %} Hello {% endcomment %}
19+
{% block geospaas_tab_contents %}
20+
<div id="default_tab">Welcome to GeoSPaaS!</div>
21+
{% endblock geospaas_tab_contents %}
2122
</div>
2223
</div>
2324
</body>

geospaas/base_viewer/urls.py

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,8 @@
88

99
geospaas_apps = config.get_setting('base_viewer', 'apps')
1010
urlpatterns = [
11-
path(
12-
route='',
13-
view=GeoSPaaSView.as_view(),
14-
name='index',
15-
kwargs={
16-
'geospaas_apps': geospaas_apps,
17-
'selected_tab': None,
18-
},
19-
)
11+
path(route='', view=GeoSPaaSView.as_view(), name='index')
2012
]
2113

2214
for geospaas_app in geospaas_apps:
23-
urlpatterns.append(
24-
path(
25-
geospaas_app['path'],
26-
include(geospaas_app['urls']),
27-
{
28-
'geospaas_apps': geospaas_apps,
29-
'selected_tab': geospaas_app['label'],
30-
}
31-
)
32-
)
15+
urlpatterns.append(path(geospaas_app['path'], include(geospaas_app['urls'])))

geospaas/base_viewer/views.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
from django.views.generic import TemplateView
22
from django.urls import reverse
33

4+
from geospaas.config import config
5+
46

57
class GeoSPaaSView(TemplateView):
68
""""""
79
template_name = 'base_viewer/geospaas.html'
10+
tab_label = None
11+
12+
def __init__(self, **kwargs):
13+
super().__init__(**kwargs)
14+
self.geospaas_apps = config.get_setting('base_viewer', 'apps')
815

916
def get_context_data(self, **kwargs):
1017
context = super().get_context_data(**kwargs)
11-
context['geospaas_apps'] = kwargs['geospaas_apps']
12-
context['selected_tab'] = kwargs['selected_tab']
13-
print('context', context)
18+
context['geospaas_apps'] = self.geospaas_apps
19+
context['selected_tab'] = self.tab_label
1420
return context
15-
16-
# def get(self, request, *args, **kwargs):
17-
# return super().get(request, *args, **kwargs)

geospaas/catalog/filters.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""Custom filters for the base geospaas API"""
2+
import rest_framework_filters
3+
from django.contrib.gis.db.models import GeometryField
4+
from django_filters.rest_framework.filters import CharFilter
5+
6+
import geospaas.catalog.models
7+
8+
9+
class TagFilter(rest_framework_filters.FilterSet):
10+
"""Filterset for tags"""
11+
class Meta:
12+
fields = {
13+
'name': '__all__',
14+
'value': '__all__',
15+
}
16+
17+
18+
class DatasetFilter(rest_framework_filters.FilterSet):
19+
"""Filter for Datasets"""
20+
21+
tags = rest_framework_filters.RelatedFilter(
22+
TagFilter,
23+
field_name='tags',
24+
queryset=geospaas.catalog.models.Tag.objects.all())
25+
26+
class Meta:
27+
model = geospaas.catalog.models.Dataset
28+
filter_overrides = {
29+
GeometryField: {
30+
'filter_class': CharFilter
31+
}
32+
}
33+
fields = {
34+
'id': '__all__',
35+
'entry_id': '__all__',
36+
'summary': '__all__',
37+
'time_coverage_start': '__all__',
38+
'time_coverage_end': '__all__',
39+
'location': '__all__',
40+
}
41+
42+
43+
44+
class DatasetURIFilter(rest_framework_filters.FilterSet):
45+
"""Filter for DatasetURIs"""
46+
dataset = rest_framework_filters.RelatedFilter(
47+
DatasetFilter,
48+
field_name='dataset',
49+
queryset=geospaas.catalog.models.Dataset.objects.all()
50+
)
51+
class Meta:
52+
model = geospaas.catalog.models.DatasetURI
53+
fields = {
54+
'uri': '__all__',
55+
}

geospaas/catalog/forms.py

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,41 @@
55

66
class BaseSearchForm(forms.Form):
77
""" Basic version of form for basic seaching of django-geospaas metadata """
8-
polygon = forms.GeometryField(label=False,
9-
widget=LeafletWidget(attrs={
10-
'settings_overrides': {
11-
'DEFAULT_CENTER': (89.0, 179.0),
12-
'DEFAULT_ZOOM': 1,
13-
'NO_GLOBALS': False,
14-
'PLUGINS': {'forms': {'auto-include': True}},
15-
}
16-
}),
17-
required=False)
18-
time_coverage_start = forms.DateTimeField(
19-
initial=timezone.datetime(2000, 1, 1, tzinfo=timezone.utc))
20-
time_coverage_end = forms.DateTimeField(initial=timezone.now())
8+
polygon = forms.GeometryField(
9+
label=False,
10+
widget=LeafletWidget(attrs={
11+
'settings_overrides': {
12+
'DEFAULT_CENTER': (89.0, 179.0),
13+
'DEFAULT_ZOOM': 1,
14+
'NO_GLOBALS': False,
15+
'PLUGINS': {'forms': {'auto-include': True}},
16+
}
17+
}),
18+
required=False)
19+
time_coverage_start = forms.DateTimeField()
20+
time_coverage_end = forms.DateTimeField()
21+
tags = forms.CharField(required=False)
22+
keywords = forms.CharField(required=False)
23+
full_text = forms.CharField(required=False)
24+
parameters = forms.CharField(required=False)
2125

22-
def filter(self, ds):
23-
""" Filtering method of the form. All filtering processes are coded here """
24-
# filtering based on time
25-
t_0 = self.cleaned_data['time_coverage_start']
26-
t_1 = self.cleaned_data['time_coverage_end']
27-
# Too early datasets are excluded from the filtering results
28-
ds = ds.exclude(time_coverage_end__lte=t_0)
26+
# def filter(self, ds):
27+
# """ Filtering method of the form. All filtering processes are coded here """
28+
# # filtering based on time
29+
# t_0 = self.cleaned_data['time_coverage_start']
30+
# t_1 = self.cleaned_data['time_coverage_end']
31+
# # Too early datasets are excluded from the filtering results
32+
# ds = ds.exclude(time_coverage_end__lte=t_0)
2933

30-
# Too late datasets are excluded from the filtering results
31-
ds = ds.exclude(time_coverage_start__gt=t_1)
34+
# # Too late datasets are excluded from the filtering results
35+
# ds = ds.exclude(time_coverage_start__gt=t_1)
3236

33-
# spatial filtering
34-
if self.cleaned_data['polygon']:
35-
# filtering by user provided polygon
36-
ds = ds.filter(
37-
geographic_location__geometry__intersects=self.cleaned_data['polygon'])
37+
# # spatial filtering
38+
# if self.cleaned_data['polygon']:
39+
# # filtering by user provided polygon
40+
# ds = ds.filter(
41+
# geographic_location__geometry__intersects=self.cleaned_data['polygon'])
3842

39-
# sorting
40-
ds = ds.order_by('time_coverage_start')
41-
return ds
43+
# # sorting
44+
# ds = ds.order_by('time_coverage_start')
45+
# return ds

geospaas/catalog/serializers.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""Serializers for the base geospaas API"""
2+
import geospaas.catalog.models
3+
4+
import rest_framework.serializers
5+
6+
7+
class DatasetSerializer(rest_framework.serializers.HyperlinkedModelSerializer):
8+
"""Serializer for Dataset objects"""
9+
class Meta:
10+
model = geospaas.catalog.models.Dataset
11+
# fields = '__all__'
12+
fields = [
13+
'entry_id',
14+
'entry_title',
15+
'time_coverage_start',
16+
'time_coverage_end',
17+
'location',
18+
'summary',
19+
# 'tags',
20+
]
21+
22+
23+
class DatasetURISerializer(rest_framework.serializers.HyperlinkedModelSerializer):
24+
"""Serializer for DatasetURI objects"""
25+
class Meta:
26+
model = geospaas.catalog.models.DatasetURI
27+
# fields = '__all__'
28+
fields = ['uri']
Lines changed: 100 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,110 @@
1-
var footprints_layer_style = {
1+
"use strict";
2+
3+
let footprints_layer_style = {
24
"color": "#0000ff",
35
"weight": 1,
46
"opacity": 0.9,
57
"fillOpacity": 0.1,
68
};
79

8-
var polygons = {};
10+
let polygons = {};
11+
12+
function display_page(page) {
13+
// clear existing contents
14+
let datasets_table = document.getElementById("datasets_table");
15+
// add the current page of datasets to the table
16+
if(page.results){
17+
datasets_table.querySelectorAll("tbody > tr").forEach((row) => {row.remove()});
18+
let newRow;
19+
let newCell;
20+
for(let dataset of page.results) {
21+
newRow = datasets_table.querySelector('tbody').insertRow();
22+
newCell = newRow.insertCell();
23+
newCell.appendChild(document.createTextNode(dataset.entry_id));
24+
}
25+
}
26+
27+
// deal with cursor pagination
28+
let previous_button = document.getElementById("datasets_previous_button");
29+
let next_button = document.getElementById("datasets_next_button");
30+
if(page.previous) {
31+
let previous_url = new URL(page.previous);
32+
previous_button.setAttribute("data-cursor", previous_url.searchParams.get('cursor'));
33+
previous_button.disabled = false;
34+
} else {
35+
previous_button.disabled = true;
36+
}
37+
if(page.next) {
38+
let next_url = new URL(page.next);
39+
next_button.setAttribute("data-cursor", next_url.searchParams.get('cursor'));
40+
next_button.disabled = false;
41+
} else {
42+
next_button.disabled = true;
43+
}
44+
}
45+
46+
function get_datasets(url, request_parameters) {
47+
let full_request_parameters = {
48+
...request_parameters,
49+
};
50+
let time_coverage_start = document.getElementById("id_time_coverage_start").value;
51+
let time_coverage_end = document.getElementById("id_time_coverage_end").value;
52+
let tags = document.getElementById("id_tags").value;
53+
let keywords = document.getElementById("id_keywords").value;
54+
let full_text = document.getElementById("id_full_text").value;
55+
let parameters = document.getElementById("id_parameters").value;
56+
57+
if(time_coverage_start) {full_request_parameters.time_coverage_end__gte = time_coverage_start;}
58+
if(time_coverage_end) {full_request_parameters.time_coverage_start__lte = time_coverage_end;}
959

10-
$(document).ready(function(){
11-
$(".dataset_row").each(function(){
12-
polygons[$(this).attr("ajax_url")] = new L.GeoJSON.AJAX(
13-
$(this).attr("ajax_url"),
14-
{style: footprints_layer_style}).addTo(window.maps[0]);
60+
61+
fetch(`${url}?` + new URLSearchParams(full_request_parameters).toString())
62+
.then(response => response.json())
63+
.then(page => display_page(page))
64+
.catch(error => console.log(`${error}: Failed to get datasets`));
65+
}
66+
67+
document.addEventListener("DOMContentLoaded", function() {
68+
// add listeners to trigger datasets search
69+
let host = `${window.location.protocol}//${window.location.host}`
70+
document.querySelectorAll(
71+
"#dataset_search_button, #datasets_previous_button, #datasets_next_button"
72+
).forEach((element) => element.addEventListener(
73+
"click",
74+
function() {
75+
let parameters = {page_size: document.getElementById("datasets_page_size").value};
76+
let cursor = this.getAttribute('data-cursor');
77+
if(cursor) {parameters.cursor = cursor;}
78+
get_datasets(`${host}${this.getAttribute('data-path')}`, parameters);
79+
}
80+
));
81+
82+
// trigger Search click if user presses enter on page size field
83+
document.getElementById("datasets_page_size").addEventListener("keypress", function(event) {
84+
if (event.key === "Enter") {
85+
event.preventDefault();
86+
document.getElementById("dataset_search_button").click();
87+
}
1588
});
1689

17-
$(".dataset_row").hover(
18-
function(){
19-
$(this).css("background-color", "#ffeeee");
20-
polygons[$(this).attr("ajax_url")].setStyle({color: '#ff0000'});
21-
},
22-
function(){
23-
$(this).css("background-color", "#ffffff");
24-
polygons[$(this).attr("ajax_url")].setStyle({color: '#0000ff'});
25-
},
26-
);
90+
91+
// // highlights dataset coverage on the map
92+
// document.querySelectorAll(".dataset_row").forEach(
93+
// function(element) {
94+
// polygons[element.ajax_url] = new L.GeoJSON.AJAX(
95+
// element.ajax_url,
96+
// {style: footprints_layer_style}).addTo(window.maps[0]);
97+
// }
98+
// );
99+
100+
// $(".dataset_row").hover(
101+
// function(){
102+
// $(this).css("background-color", "#ffeeee");
103+
// polygons[$(this).attr("ajax_url")].setStyle({color: '#ff0000'});
104+
// },
105+
// function(){
106+
// $(this).css("background-color", "#ffffff");
107+
// polygons[$(this).attr("ajax_url")].setStyle({color: '#0000ff'});
108+
// },
109+
// );
27110
});

0 commit comments

Comments
 (0)