Skip to content

Commit

Permalink
Add layer autocomplete to context layers page (#4301)
Browse files Browse the repository at this point in the history
* Add layer autocomplete to context layers page

* Update django to 4.2.16
  • Loading branch information
dimasciput authored Oct 9, 2024
1 parent 3a224a6 commit 9a77563
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 15 deletions.
5 changes: 4 additions & 1 deletion bims/api_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
from bims.api_views.hide_popup_info_user import HidePopupInfoUser
from bims.api_views.send_notification_to_validator import \
SendNotificationValidation
from bims.views.context_layers import ContextLayerGroup
from bims.views.context_layers import ContextLayerGroup, CloudNativeLayerAutoCompleteAPI
from bims.views.locate import filter_farm_ids_view, get_farm_view
from bims.api_views.user_boundary import (
UserBoundaryList,
Expand Down Expand Up @@ -391,4 +391,7 @@
name='context-layers-group'),
path('context-layer-group/<int:pk>/',
ContextLayerGroup.as_view(),),
path('cloud-native-layer-autocomplete/',
CloudNativeLayerAutoCompleteAPI.as_view(),
name='cloud-native-layer-autocomplete'),
]
22 changes: 22 additions & 0 deletions bims/static/react/css/ContextLayers.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.autocomplete-results {
list-style: none;
padding: 0;
margin: 0;
border: 1px solid #ddd;
background-color: white;
width: 95%; /* Make the width match the input field */
max-height: 150px; /* Control the maximum height */
overflow-y: auto; /* Add scroll if too many results */
position: absolute; /* Ensure the dropdown is positioned relative to the input */
z-index: 9999; /* Ensure it appears above other elements */
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* Optional: Add shadow for better visibility */
}

.autocomplete-item {
padding: 10px;
cursor: pointer;
}

.autocomplete-item:hover {
background-color: #f0f0f0;
}
1 change: 1 addition & 0 deletions bims/static/react/js/ContextLayersView.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react';
import axios from "axios";
import '../css/ContextLayers.scss';
import {createRoot} from "react-dom/client";
import {ContextGroupDetailModal} from "./components/ContextGroupDetailModal";
import {ContextGroupCard} from "./components/ContextGroupCard";
Expand Down
99 changes: 89 additions & 10 deletions bims/static/react/js/components/ContextGroupDetailModal.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,84 @@
import React, { useState, useEffect, useRef } from 'react';
import {
Button, Form, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader} from "reactstrap";
import React, {useEffect, useState} from "react";
import axios from "axios";


export const AutocompleteInput = ({ groupValues, updateValue, url }) => {
const [autocompleteResults, setAutocompleteResults] = useState([]);
const [inputValue, setInputValue] = useState('')
const inputRef = useRef(null);

useEffect(() => {
setInputValue(groupValues.native_layer_name)
}, [groupValues.native_layer_name])

const handleAutocompleteInputChange = async (e) => {
const query = e.target.value;
setInputValue(query)
if (query.length > 2) {
try {
const response = await axios.get(`${url}?q=${query}`);
setAutocompleteResults(response.data);
} catch (error) {
console.error("Error fetching autocomplete results:", error);
}
} else {
setAutocompleteResults([]);
}
};

const handleInputSelect = () => {
if (inputRef.current) {
inputRef.current.focus();
inputRef.current.select();
}
}

const handleAutocompleteSelect = (layer) => {
updateValue(layer.unique_id, 'key');
updateValue(layer.unique_id, 'geocontext_group_key');
updateValue(layer.name, 'native_layer_name')
setInputValue(layer.name)

setAutocompleteResults([]);
};

return (
<div style={{ position: 'relative' }}>
<Input
type="text"
id="groupKey"
value={inputValue}
onChange={handleAutocompleteInputChange}
onClick={handleInputSelect}
placeholder="Start typing to search..."
innerRef={inputRef}
/>
{autocompleteResults.length > 0 && (
<ul className="autocomplete-results">
{autocompleteResults.map((layer) => (
<li
key={layer.id}
onClick={() => handleAutocompleteSelect(layer)}
className="autocomplete-item"
>
{layer.name}
</li>
))}
</ul>
)}
</div>
);
};


export const ContextGroupDetailModal = ({ show, handleClose, group, handleSave }) => {
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
const [groupValues, setGroupValues] = useState({
id: '',
layer_name: '',
native_layer_name: '',
name: '',
key: '',
active: false,
Expand All @@ -21,6 +92,7 @@ export const ContextGroupDetailModal = ({ show, handleClose, group, handleSave }
setGroupValues({
id: group.id,
layer_name: group.layer_name ? group.layer_name : '',
native_layer_name: group.native_layer_name,
name: group.name,
key: group.key,
active: group.active,
Expand Down Expand Up @@ -62,7 +134,7 @@ export const ContextGroupDetailModal = ({ show, handleClose, group, handleSave }
/>
</FormGroup>
{
!group.is_native_layer || (
!group.is_native_layer && (
<FormGroup>
<Label for="groupKey">GeoContext Group Key</Label>
<Input
Expand All @@ -76,13 +148,20 @@ export const ContextGroupDetailModal = ({ show, handleClose, group, handleSave }
}

<FormGroup>
<Label for="groupKey">Service Key</Label>
<Input
type="text"
id="groupKey"
value={groupValues.key}
onChange={(e) => updateValue(e.target.value, 'key')}
/>
<Label for="groupKey">{group.is_native_layer ? 'Layer':'Service Key'}</Label>
{group.is_native_layer ? (
<AutocompleteInput
groupValues={groupValues}
updateValue={updateValue}
url={'/api/cloud-native-layer-autocomplete/'}/>
) : (
<Input
type="text"
id="groupKey"
value={groupValues.key}
onChange={(e) => updateValue(e.target.value, 'key')}
/>
)}
</FormGroup>

<FormGroup>
Expand All @@ -101,7 +180,7 @@ export const ContextGroupDetailModal = ({ show, handleClose, group, handleSave }
</div>
</FormGroup>
{
!group.is_native_layer || (
!group.is_native_layer && (
<>
<FormGroup>
<Label for="layerName">Layer Name</Label>
Expand Down
30 changes: 29 additions & 1 deletion bims/views/context_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,30 @@
LocationContextGroup
)
from bims.utils.uuid import is_uuid
from cloud_native_gis.models import Layer
from cloud_native_gis.serializer.layer import LayerSerializer


class NativeLayerSerializer(LayerSerializer):
class Meta:
model = Layer
fields = '__all__'


class LocationContextGroupSerializer(serializers.ModelSerializer):

is_native_layer = serializers.SerializerMethodField()
native_layer_name = serializers.SerializerMethodField()

def get_native_layer_name(self, obj: LocationContextGroup):
if obj.key and is_uuid(obj.key):
layer = Layer.objects.get(unique_id=obj.key)
return layer.name
return ''

def get_is_native_layer(self, obj: LocationContextGroup):
if obj.key:
return not is_uuid(obj.key)
return is_uuid(obj.key)
return False

class Meta:
Expand Down Expand Up @@ -67,3 +82,16 @@ def get(self, request, *args):
location_context_groups, many=True
)
return Response(context_group_data.data)


class CloudNativeLayerAutoCompleteAPI(APIView):
def get(self, request, *args):
query = request.query_params.get('q', '')
layers = Layer.objects.filter(
name__icontains=query
)
serializer = NativeLayerSerializer(
layers, many=True, context={
'request': request
})
return Response(serializer.data)
2 changes: 1 addition & 1 deletion deployment/docker/REQUIREMENTS.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Django==4.2.15
Django==4.2.16
psycopg2==2.9.9
django-braces==1.14.0
django-model-utils==4.0.0
Expand Down
2 changes: 1 addition & 1 deletion deployment/docker/temp/REQUIREMENTS.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Django==4.2.15
Django==4.2.16
psycopg2==2.9.9
django-braces==1.14.0
django-model-utils==4.0.0
Expand Down
2 changes: 1 addition & 1 deletion deployment/production/REQUIREMENTS.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Django==4.2.15
Django==4.2.16
psycopg2==2.9.9
django-braces==1.14.0
django-model-utils==4.0.0
Expand Down

0 comments on commit 9a77563

Please sign in to comment.