Skip to content

Commit

Permalink
feat: add sub types to wireline filter
Browse files Browse the repository at this point in the history
Closes #108
  • Loading branch information
stdavis committed Apr 7, 2021
1 parent 79c78b3 commit 100fcb7
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 37 deletions.
12 changes: 10 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ const ErrorFallback = ({ error }) => {

const defaultFilter = {
transType: {
wireline: true,
cable: true,
dsl: true,
fiber: true,
fixed: true,
mobile: false,
},
Expand All @@ -31,7 +33,13 @@ const defaultFilter = {
function filterReducer(draft, action) {
switch (action.type) {
case 'transType':
draft.transType[action.meta] = action.payload;
if (action.meta === 'wireline') {
draft.transType.cable = action.payload;
draft.transType.dsl = action.payload;
draft.transType.fiber = action.payload;
} else {
draft.transType[action.meta] = action.payload;
}
break;

case 'reset':
Expand Down
9 changes: 0 additions & 9 deletions src/App.test.js

This file was deleted.

50 changes: 44 additions & 6 deletions src/components/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,25 @@ import { FormGroup, Label, CustomInput, Button } from 'reactstrap';
import propTypes from 'prop-types';

const Sidebar = ({ filter, dispatchFilter }) => {
function onTransTechClick(event) {
function onTransTechChange(event) {
dispatchFilter({
type: 'transType',
meta: event.target.value,
payload: event.target.checked,
});
}

const wirelineChecked = filter.transType.cable && filter.transType.dsl && filter.transType.fiber;
const wirelineCheckbox = React.useRef(null);
React.useEffect(() => {
const indeterminate =
!wirelineChecked && (filter.transType.cable || filter.transType.dsl || filter.transType.fiber);

if (wirelineCheckbox.current) {
wirelineCheckbox.current.indeterminate = indeterminate;
}
}, [filter.transType.cable, filter.transType.dsl, filter.transType.fiber, wirelineChecked]);

return (
<div className="sidebar">
<h2>Utah Residential Broadband</h2>
Expand All @@ -22,30 +33,57 @@ const Sidebar = ({ filter, dispatchFilter }) => {
id="wirelineCheckbox"
type="checkbox"
label="Wireline"
checked={filter.transType.wireline}
onChange={onTransTechClick}
checked={wirelineChecked}
innerRef={wirelineCheckbox}
onChange={onTransTechChange}
value="wireline"
/>
<div className="ml-4">
<CustomInput
id="cableCheckbox"
type="checkbox"
label="Cable"
checked={filter.transType.cable}
onChange={onTransTechChange}
value="cable"
/>
<CustomInput
id="dslCheckbox"
type="checkbox"
label="DSL"
checked={filter.transType.dsl}
onChange={onTransTechChange}
value="dsl"
/>
<CustomInput
id="fiberCheckbox"
type="checkbox"
label="Fiber"
checked={filter.transType.fiber}
onChange={onTransTechChange}
value="fiber"
/>
</div>
<CustomInput
id="fixedCheckbox"
type="checkbox"
label="Fixed Wireless"
checked={filter.transType.fixed}
onChange={onTransTechClick}
onChange={onTransTechChange}
value="fixed"
/>
<CustomInput
id="mobileCheckbox"
type="checkbox"
label="Mobile Wireless"
checked={filter.transType.mobile}
onChange={onTransTechClick}
onChange={onTransTechChange}
value="mobile"
/>
</div>
</FormGroup>
<Button className="w-100" onClick={() => dispatchFilter({ type: 'reset' })}>
reset filter
Reset Filter
</Button>
</div>
);
Expand Down
20 changes: 14 additions & 6 deletions src/components/Sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@
color: $text-default;
padding: 1.5em;
background-color: $default;
.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {
border-color: $text-default;
background-color: $text-default;
}
.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23333' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e");
.custom-checkbox {
.custom-control-input {
&:checked ~ .custom-control-label::before,
&:indeterminate ~ .custom-control-label::before {
border-color: $text-default;
background-color: $text-default;
}
&:checked ~ .custom-control-label::after {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23333' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e");
}
&:indeterminate ~ .custom-control-label::after {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23333' d='M0 2h4'/%3e%3c/svg%3e");
}
}
}
}
59 changes: 45 additions & 14 deletions src/components/esrijs/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,46 @@ import React, { useRef, useEffect } from 'react';
import WebMap from '@arcgis/core/WebMap';
import MapView from '@arcgis/core/views/MapView';
import Legend from '@arcgis/core/widgets/Legend';
import config from '../../config';

export function getQueryFromFilter(filter) {
const transTypeValues = Object.keys(filter.transType).reduce((previous, key) => {
if (filter.transType[key] && config.transTechValues[key]) {
return previous.concat(config.transTechValues[key]);
}
return previous;
}, []);

return `${config.fieldNames.TransTech} IN (${transTypeValues.join(',')})`;
}

const Map = ({ onClick, setView, view, webMapId, children, zoomToExtent, initialExtent, filter }) => {
const mapDiv = useRef(null);

// these are layer views
const wirelineLayers = useRef([]);
const fixedLayers = useRef([]);
const mobileLayers = useRef([]);

const syncFilter = React.useCallback(() => {
const sync = (type) => {
return (layer) => (layer.visible = filter.transType[type]);
const syncMapWithFilter = React.useCallback(() => {
const syncVisibility = (visible) => {
return (layer) => (layer.visible = visible);
};
wirelineLayers.current.forEach(sync('wireline'));
fixedLayers.current.forEach(sync('fixed'));
mobileLayers.current.forEach(sync('mobile'));
fixedLayers.current.forEach(syncVisibility(filter.transType.fixed));
mobileLayers.current.forEach(syncVisibility(filter.transType.mobile));
wirelineLayers.current.forEach(
syncVisibility(filter.transType.cable || filter.transType.dsl || filter.transType.fiber)
);

// for each visible layer, apply def query
const visibleLayers = fixedLayers.current
.concat(mobileLayers.current, wirelineLayers.current)
.filter((layer) => layer.visible);

const query = getQueryFromFilter(filter);
console.log('new query: ', query);

visibleLayers.forEach((layer) => (layer.filter = { where: query }));
}, [filter]);

useEffect(() => {
Expand All @@ -40,12 +66,17 @@ const Map = ({ onClick, setView, view, webMapId, children, zoomToExtent, initial
},
});

map.when(() => {
wirelineLayers.current = map.layers.filter((layer) => layer.title.toLowerCase().match(/wireline/));
fixedLayers.current = map.layers.filter((layer) => layer.title.toLowerCase().match(/fixed/));
mobileLayers.current = map.layers.filter((layer) => layer.title.toLowerCase().match(/mobile/));
function getLayerViews(regex) {
const layers = map.layers.filter((layer) => layer.title.toLowerCase().match(regex));

return Promise.all(layers.map((layer) => mapView.whenLayerView(layer)));
}
map.when(async () => {
wirelineLayers.current = await getLayerViews(/wireline/);
fixedLayers.current = await getLayerViews(/fixed/);
mobileLayers.current = await getLayerViews(/mobile/);

syncFilter();
syncMapWithFilter();
mapView.when(() => {
const legend = new Legend({
view: mapView,
Expand All @@ -62,7 +93,7 @@ const Map = ({ onClick, setView, view, webMapId, children, zoomToExtent, initial
mapView.on('click', onClick);

setView(mapView);
}, [initialExtent, onClick, setView, syncFilter, view, webMapId]);
}, [initialExtent, onClick, setView, syncMapWithFilter, view, webMapId]);

useEffect(() => {
if (!zoomToExtent || !view) return;
Expand All @@ -71,8 +102,8 @@ const Map = ({ onClick, setView, view, webMapId, children, zoomToExtent, initial
}, [zoomToExtent, view]);

React.useEffect(() => {
syncFilter();
}, [filter, syncFilter]);
syncMapWithFilter();
}, [filter, syncMapWithFilter]);

return (
<div className="map-container" ref={mapDiv}>
Expand Down
31 changes: 31 additions & 0 deletions src/components/esrijs/Map.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import config from '../../config';
import { getQueryFromFilter } from './Map';

const fieldNames = config.fieldNames;

describe('Map', () => {
describe('getQueryFromFilter', () => {
it('builds the correct trans type query', () => {
const defaultTransType = {
dsl: false,
cable: false,
fiber: false,
fixed: false,
mobile: false,
wireline: false,
};
const tests = [
[`${fieldNames.TransTech} IN (50)`, { transType: { ...defaultTransType, fiber: true } }],
[`${fieldNames.TransTech} IN (10,20,50)`, { transType: { ...defaultTransType, dsl: true, fiber: true } }],
[
`${fieldNames.TransTech} IN (10,20,30,40,41,50)`,
{ transType: { ...defaultTransType, dsl: true, fiber: true, cable: true, wireline: true } },
],
];

tests.forEach(([expected, input]) => {
expect(getQueryFromFilter(input)).toEqual(expected);
});
});
});
});
10 changes: 10 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ const config = {
urls: {
masquerade: 'https://masquerade-kkktr623oa-uc.a.run.app/arcgis/rest/services/UtahLocator/GeocodeServer',
},
fieldNames: {
TransTech: 'TransTech',
},
transTechValues: {
dsl: [10, 20],
cable: [30, 40, 41],
fiber: [50],
fixed: [70, 71],
mobile: [80],
},
};

export default config;

0 comments on commit 100fcb7

Please sign in to comment.