Skip to content

Commit

Permalink
New Context Layer type based on related table (unicef-drp#257)
Browse files Browse the repository at this point in the history
* Context Layer based on related table

Related Field on general context layer form

WIP

Filter related table data

Clean django code

Clean django code

Clean django code

Clean django code

Clean django code

* Fix autoformat changes

* Rename fields
  • Loading branch information
fpsampayo authored Apr 4, 2024
1 parent 8764167 commit 7423cca
Show file tree
Hide file tree
Showing 13 changed files with 521 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* GeoSight is UNICEF's geospatial web-based business intelligence platform.
*
* Contact : [email protected]
*
* .. note:: This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* __author__ = '[email protected]'
* __date__ = '20/03/2024'
* __copyright__ = ('Copyright 2024, Unicef')
*/

import React, { Fragment, useEffect, useState } from 'react';


import { SelectWithSearch } from "../../../../components/Input/SelectWithSearch";
import WhereInputModal from "../../../../components/SqlQueryGenerator/WhereInputModal";
import { getRelatedTableFields } from "../../../../utils/relatedTable";
import { fetchingData } from "../../../../Requests";
import { dictDeepCopy } from "../../../../utils/main";


/**
* Indicator Form App
* @param {dict} data Data of context layer.
* @param {boolean} checkConfig Checking config.
*/
export default function RelatedTableFields(
{
data,
onSetData
}
) {
const [relatedTableInfo, setRelatedTableInfo] = useState(null)
const [relatedTableData, setRelatedTableData] = useState(null)

// Loading data
useEffect(() => {
if (!open) {
return
}
if (data.related_table) {
const params = {}
const url_info = `/api/related-table/${data.related_table}`
const url_data = `/api/related-table/${data.related_table}/data`
setRelatedTableInfo(null)
setRelatedTableData(null)
fetchingData(
url_data, params, {}, function (response, error) {
setRelatedTableData(dictDeepCopy(response))
}
)
fetchingData(
url_info, params, {}, function (response, error) {
setRelatedTableInfo(dictDeepCopy(response))
}
)
}
}, [data.related_table])

const relatedFields = relatedTableInfo && relatedTableData ? getRelatedTableFields(relatedTableInfo, relatedTableData) : []
return (
<div>
<div className='BasicFormSection'>
<div className='form-label'>Latitude Field</div>
<div className='InputInLine'>
<SelectWithSearch
value={data.latitude_field}
onChangeFn={evt => {
onSetData({ ...data, latitude_field: evt })
}}
options={relatedFields.filter(rf => rf.type === 'number').map(rf => rf.name)}
className='FilterInput' />
</div>
</div>
<div className='BasicFormSection'>
<div className='form-label'>Longitude Field</div>
<div className='InputInLine'>
<SelectWithSearch
value={data.longitude_field}
onChangeFn={evt => {
onSetData({ ...data, longitude_field: evt })
}}
options={relatedFields.filter(rf => rf.type === 'number').map(rf => rf.name)}
className='FilterInput' />
</div>
</div>
<div className='BasicFormSection'>
<div className='form-label'>Datetime field</div>
<div className='InputInLine'>
<SelectWithSearch
value={data.datetime_field}
onChangeFn={evt => {
onSetData({ ...data, datetime_field: evt })
}}
options={relatedFields.filter(rf => rf.type === 'date').map(rf => rf.name)}
className='FilterInput' />
</div>
</div>

<WhereInputModal
value={data.query ? data.query : ''}
fields={relatedFields}
setValue={evt => {
onSetData({ ...data, query: evt })
}}
title={"Filter the Data"}
/>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@ import { render } from '../../../../app';
import { store } from '../../../../store/admin';
import { SaveButton } from "../../../../components/Elements/Button";
import Admin, { pageNames } from '../../index';
import { AdminForm } from '../../Components/AdminForm'
import StyleConfig from '../StyleConfig'
import { AdminForm } from '../../Components/AdminForm';
import StyleConfig from '../StyleConfig';
import RelatedTableFields from './RelatedTableFields';
import DjangoTemplateForm from "../../Components/AdminForm/DjangoTemplateForm";
import { resourceActions } from "../List";
import { dictDeepCopy } from "../../../../utils/main";

import './style.scss';

let currentArcGis = null
let currentRelatedTable = null
let init = false
/**
* Context Layer Form App
Expand Down Expand Up @@ -87,21 +89,36 @@ export default function ContextLayerForm() {
$('*[name="label_styles"]').val(JSON.stringify(newData['label_styles']))
$('*[name="data_fields"]').val(JSON.stringify(newData['data_fields']))
$('*[name="styles"]').val(JSON.stringify(newData['styles']))
$('*[name="latitude_field"]').val(newData['latitude_field'])
$('*[name="longitude_field"]').val(newData['longitude_field'])
$('*[name="query"]').val(newData['query'])
$('*[name="datetime_field"]').val(newData['datetime_field'])
}
}

const typeChange = (value) => {
if (value === 'ARCGIS') {
$('div[data-wrapper-name="arcgis_config"]').show()
} else {
$('div[data-wrapper-name="related_table"]').hide()
} else if (value === 'Related Table') {
$('div[data-wrapper-name="arcgis_config"]').hide()
$('div[data-wrapper-name="token"]').hide()
$('div[data-wrapper-name="username"]').hide()
$('div[data-wrapper-name="password"]').hide()
$('div[data-wrapper-name="url"]').hide()
$('div[data-wrapper-name="related_table"]').show()
}
else {
$('div[data-wrapper-name="arcgis_config"]').hide()
$('div[data-wrapper-name="related_table"]').hide()
$('div[data-wrapper-name="url"]').show()
}
setData({ ...data, layer_type: value })
}

const arcGisConfigChange = (value) => {
currentArcGis = value
if (!value) {
if (!value && data.layer_type === 'ARCGIS') {
$('div[data-wrapper-name="token"]').show()
$('div[data-wrapper-name="username"]').show()
$('div[data-wrapper-name="password"]').show()
Expand All @@ -116,6 +133,16 @@ export default function ContextLayerForm() {
})
}
}

const relatedTableConfigChange = (value) => {
currentRelatedTable = value
if (value) {
setData({
...data,
related_table: value
})
}
}
return (
<Admin
minifySideNavigation={true}
Expand Down Expand Up @@ -162,8 +189,8 @@ export default function ContextLayerForm() {
} else if (name === 'arcgis_config') {
arcGisConfigChange(value)
setDataFn()
} else {
setDataFn()
} else if (name === 'related_table') {
relatedTableConfigChange(value)
}
}}
>
Expand All @@ -181,6 +208,12 @@ export default function ContextLayerForm() {
onChange={evt => {
}}
/>
{data.layer_type === 'Related Table' ?
<RelatedTableFields
data={data}
onSetData={updateData}
/> : undefined
}
</DjangoTemplateForm>
),
'Preview': (
Expand All @@ -192,8 +225,8 @@ export default function ContextLayerForm() {
useOverrideLabel={false}
/>
),
'Fields': <div/>,
'Label': <div/>,
'Fields': <div />,
'Label': <div />,
}}
/>
</Admin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default function MapConfig({ data, layerInput }) {
// When layer input changed, remove from map
useEffect(() => {
if (map) {
const id = 'Context-Layer'
const id = data.id ? `context-layer-${data.id}` : 'context-layer'
contextLayerRendering(id, data, layerInput, map)
}
}, [map, layerInput]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import MapConfig from './Map'
import ArcgisConfig from './Arcgis'
import { useDispatch } from "react-redux";
import { getLayer } from '../../../Dashboard/LeftPanel/ContextLayers/Layer'
import { defaultPointStyle, defaultVectorTyleStyle } from './layerStyles';

import './style.scss';

Expand Down Expand Up @@ -58,6 +59,16 @@ export default function StyleConfig(
getLayer(data, setLayer, setLegend, setError, dispatch, setLayerDataClass);
}, [data, tab]);

useEffect(() => {
if (!data.styles && data.layer_type === 'Related Table') {
setData({
...data,
styles: JSON.stringify(defaultPointStyle, null, 4),
override_style: true
})
}
}, [data]);

useEffect(() => {
if (layerDataClass) {
setLayerData(layerDataClass)
Expand Down Expand Up @@ -125,15 +136,18 @@ export default function StyleConfig(
}
</div>
</div>
<MapConfig data={data} layerInput={{
layer: layer,
layer_type: data.layer_type,
render: true
}}/>
<MapConfig
data={data}
layerInput={{
layer: layer,
layer_type: data.layer_type,
render: true
}}
/>
</div> : ""
}
{
data.layer_type === 'Vector Tile' ? <>
data.layer_type === 'Vector Tile' || data.layer_type === 'Related Table' ? <>
<div className='Style'>
<div><b>Layers</b></div>
<span>
Expand All @@ -147,37 +161,10 @@ export default function StyleConfig(
<br/>
<textarea
placeholder={
JSON.stringify([
{
id: "country-line",
type: "line",
source: "source",
"source-layer": "countries",
filter: [
"==",
"$type",
"Polygon"
],
paint: {
"line-width": 1,
"line-color": "#AAAAAA"
}
},
{
id: "country-fill",
type: "fill",
source: "source",
"source-layer": "countries",
filter: [
"==",
"$type",
"Polygon"
],
paint: {
"fill-opacity": 0
}
}
], null, 4)
JSON.stringify(data.layer_type === 'Related Table' ?
defaultPointStyle :
defaultVectorTyleStyle,
null, 4)
}
defaultValue={data.styles}
style={{ minHeight: "90%" }}
Expand Down Expand Up @@ -211,7 +198,7 @@ export default function StyleConfig(
/> :
<Fragment>
<div className='ArcgisConfig Fields form-helptext'>
Config is not Arcgis
Config is not Arcgis or Related Table Type
</div>
</Fragment>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* GeoSight is UNICEF's geospatial web-based business intelligence platform.
*
* Contact : [email protected]
*
* .. note:: This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* __author__ = '[email protected]'
* __date__ = '27/03/2024'
* __copyright__ = ('Copyright 2024, Unicef')
*/

export const defaultVectorTyleStyle = [
{
id: "country-line",
type: "line",
source: "source",
"source-layer": "countries",
filter: [
"==",
"$type",
"Polygon"
],
paint: {
"line-width": 1,
"line-color": "#AAAAAA"
}
},
{
id: "country-fill",
type: "fill",
source: "source",
"source-layer": "countries",
filter: [
"==",
"$type",
"Polygon"
],
paint: {
"fill-opacity": 0
}
}
];

export const defaultPointStyle = [{
id: 'pointLayer',
type: 'circle',
source: 'source',
paint: {
'circle-color': '#ff7800',
'circle-opacity': 0.6
},
'filter': ['==', '$type', 'Point']
}];
Loading

0 comments on commit 7423cca

Please sign in to comment.