From f418231b6b2f5e030a0d2dcc390c314602b1f740 Mon Sep 17 00:00:00 2001
From: Anton Tananaev <anton@traccar.org>
Date: Sat, 6 Apr 2024 09:22:10 -0700
Subject: Move modern to the top

---
 src/common/components/SelectField.jsx | 77 +++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 src/common/components/SelectField.jsx

(limited to 'src/common/components/SelectField.jsx')

diff --git a/src/common/components/SelectField.jsx b/src/common/components/SelectField.jsx
new file mode 100644
index 00000000..db8c30b0
--- /dev/null
+++ b/src/common/components/SelectField.jsx
@@ -0,0 +1,77 @@
+import {
+  FormControl, InputLabel, MenuItem, Select, Autocomplete, TextField,
+} from '@mui/material';
+import React, { useState } from 'react';
+import { useEffectAsync } from '../../reactHelper';
+
+const SelectField = ({
+  label,
+  fullWidth,
+  multiple,
+  value = null,
+  emptyValue = null,
+  emptyTitle = '',
+  onChange,
+  endpoint,
+  data,
+  keyGetter = (item) => item.id,
+  titleGetter = (item) => item.name,
+}) => {
+  const [items, setItems] = useState(data);
+
+  const getOptionLabel = (option) => {
+    if (typeof option !== 'object') {
+      option = items.find((obj) => keyGetter(obj) === option);
+    }
+    return option ? titleGetter(option) : emptyTitle;
+  };
+
+  useEffectAsync(async () => {
+    if (endpoint) {
+      const response = await fetch(endpoint);
+      if (response.ok) {
+        setItems(await response.json());
+      } else {
+        throw Error(await response.text());
+      }
+    }
+  }, []);
+
+  if (items) {
+    return (
+      <FormControl fullWidth={fullWidth}>
+        {multiple ? (
+          <>
+            <InputLabel>{label}</InputLabel>
+            <Select
+              label={label}
+              multiple
+              value={value}
+              onChange={onChange}
+            >
+              {items.map((item) => (
+                <MenuItem key={keyGetter(item)} value={keyGetter(item)}>{titleGetter(item)}</MenuItem>
+              ))}
+            </Select>
+          </>
+        ) : (
+          <Autocomplete
+            size="small"
+            options={items}
+            getOptionLabel={getOptionLabel}
+            renderOption={(props, option) => (
+              <MenuItem {...props} key={keyGetter(option)} value={keyGetter(option)}>{titleGetter(option)}</MenuItem>
+            )}
+            isOptionEqualToValue={(option, value) => keyGetter(option) === value}
+            value={value}
+            onChange={(_, value) => onChange({ target: { value: value ? keyGetter(value) : emptyValue } })}
+            renderInput={(params) => <TextField {...params} label={label} />}
+          />
+        )}
+      </FormControl>
+    );
+  }
+  return null;
+};
+
+export default SelectField;
-- 
cgit v1.2.3

