From df0639f61e438cbd83f3b69d1dd7b681c94e914a Mon Sep 17 00:00:00 2001
From: Tom Curtis <105217023+dinosaursrarr@users.noreply.github.com>
Date: Thu, 2 Feb 2023 14:04:13 +0000
Subject: [PATCH] Support schema.Location in pixlet serve (#585)
---
src/features/schema/FieldDetails.jsx | 3 +-
.../schema/fields/location/InputSlider.jsx | 79 +++++++++++++
.../schema/fields/location/LocationForm.jsx | 107 ++++++++++++++++++
3 files changed, 188 insertions(+), 1 deletion(-)
create mode 100644 src/features/schema/fields/location/InputSlider.jsx
create mode 100644 src/features/schema/fields/location/LocationForm.jsx
diff --git a/src/features/schema/FieldDetails.jsx b/src/features/schema/FieldDetails.jsx
index e73ff16985..4ff4a89d97 100644
--- a/src/features/schema/FieldDetails.jsx
+++ b/src/features/schema/FieldDetails.jsx
@@ -5,6 +5,7 @@ import PhotoSelect from './fields/photoselect/PhotoSelect';
import Toggle from './fields/Toggle';
import DateTime from './fields/DateTime';
import Dropdown from './fields/Dropdown';
+import LocationForm from './fields/location/LocationForm';
import TextInput from './fields/TextInput';
import Typeahead from './fields/Typeahead';
import Typography from '@mui/material/Typography';
@@ -17,7 +18,7 @@ export default function FieldDetails({ field }) {
case 'dropdown':
return
case 'location':
- return schema.Location() is not yet supported in pixlet, but is supported in the community repo. Be on the lookout for this field to be available in a future release.
+ return
case 'locationbased':
return schema.LocationBased() is not yet supported in pixlet, but is supported in the community repo. Be on the lookout for this field to be available in a future release.
case 'oauth2':
diff --git a/src/features/schema/fields/location/InputSlider.jsx b/src/features/schema/fields/location/InputSlider.jsx
new file mode 100644
index 0000000000..884997567e
--- /dev/null
+++ b/src/features/schema/fields/location/InputSlider.jsx
@@ -0,0 +1,79 @@
+// Largely based on https://mui.com/material-ui/react-slider/#InputSlider.js
+import React, { useState } from 'react';
+
+import { styled } from '@mui/material/styles';
+import Box from '@mui/material/Box';
+import Grid from '@mui/material/Grid';
+import Typography from '@mui/material/Typography';
+import Slider from '@mui/material/Slider';
+import MuiInput from '@mui/material/Input';
+
+const Input = styled(MuiInput)`
+ width: 80px;
+`;
+
+export default function InputSlider({ min, max, step, defaultValue, onChange}) {
+ const [value, setValue] = useState(defaultValue);
+
+ const handleSliderChange = (event, newValue) => {
+ setValue(newValue);
+ onChange(event);
+ };
+
+ const handleInputChange = (event) => {
+ if (event.target.value === '') {
+ setValue('');
+ onChange(event);
+ return;
+ }
+ const value = Number(event.target.value);
+ if (value < min) {
+ setValue(min);
+ } else if (value > max) {
+ setValue(max);
+ } else {
+ setValue(value);
+ }
+ onChange(event);
+ };
+
+ const handleBlur = () => {
+ if (value < min) {
+ setValue(min);
+ } else if (value > max) {
+ setValue(max);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/features/schema/fields/location/LocationForm.jsx b/src/features/schema/fields/location/LocationForm.jsx
new file mode 100644
index 0000000000..160436eed3
--- /dev/null
+++ b/src/features/schema/fields/location/LocationForm.jsx
@@ -0,0 +1,107 @@
+import React, { useState, useEffect } from 'react';
+import { useSelector, useDispatch } from 'react-redux';
+
+import InputLabel from '@mui/material/InputLabel';
+import MenuItem from '@mui/material/MenuItem';
+import FormControl from '@mui/material/FormControl';
+import Select from '@mui/material/Select';
+import TextField from '@mui/material/TextField';
+import Typography from '@mui/material/Typography';
+
+import InputSlider from './InputSlider';
+import { set } from '../../../config/configSlice';
+
+export default function LocationForm({ field }) {
+ const [value, setValue] = useState({
+ // Default to Brooklyn, because that's where tidbyt folks
+ // are and we can only dispatch a location object which
+ // has all fields set.
+ 'lat': 40.6782,
+ 'lng': -73.9442,
+ 'locality': 'Brooklyn, New York',
+ 'timezone': 'America/New_York',
+ // But overwrite with app-specific defaults set in config.
+ ...field.default
+ });
+
+ const config = useSelector(state => state.config);
+
+ const dispatch = useDispatch();
+
+ useEffect(() => {
+ if (field.id in config) {
+ setValue(JSON.parse(config[field.id].value));
+ } else if (field.default) {
+ dispatch(set({
+ id: field.id,
+ value: field.default,
+ }));
+ }
+ }, [])
+
+ const setPart = (partName, partValue) => {
+ let newValue = {...value};
+ newValue[partName] = partValue;
+ setValue(newValue);
+ dispatch(set({
+ id: field.id,
+ value: JSON.stringify(newValue),
+ }));
+ }
+
+ const onChangeLatitude = (event) => {
+ setPart('lat', event.target.value);
+ }
+
+ const onChangeLongitude = (event) => {
+ setPart('lng', event.target.value);
+ }
+
+ const onChangeLocality = (event) => {
+ setPart('locality', event.target.value);
+ }
+
+ const onChangeTimezone = (event) => {
+ setPart('timezone', event.target.value);
+ }
+
+ return (
+
+ Latitude
+
+
+ Longitude
+
+
+ Locality
+
+ Timezone
+
+
+ );
+}
\ No newline at end of file