Skip to content

Commit

Permalink
wip: Modify SelectField so that it uses Autocomplete component instea…
Browse files Browse the repository at this point in the history
…d of Select with single select
  • Loading branch information
jinzo committed Jan 19, 2024
1 parent bf2c172 commit 783eccb
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 27 deletions.
58 changes: 43 additions & 15 deletions modern/src/common/components/SelectField.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
FormControl, InputLabel, MenuItem, Select,
FormControl, InputLabel, MenuItem, Select, Autocomplete, TextField
} from '@mui/material';
import React, { useState } from 'react';
import { useEffectAsync } from '../../reactHelper';
Expand All @@ -14,6 +14,7 @@ const SelectField = ({
onChange,
endpoint,
data,
keyField = 'id',
keyGetter = (item) => item.id,
titleGetter = (item) => item.name,
}) => {
Expand All @@ -33,20 +34,47 @@ const SelectField = ({
if (items) {
return (
<FormControl fullWidth={fullWidth}>
<InputLabel>{label}</InputLabel>
<Select
label={label}
multiple={multiple}
value={value}
onChange={onChange}
>
{!multiple && emptyValue !== null && (
<MenuItem value={emptyValue}>{emptyTitle}</MenuItem>
)}
{items.map((item) => (
<MenuItem key={keyGetter(item)} value={keyGetter(item)}>{titleGetter(item)}</MenuItem>
))}
</Select>
{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={(option) => {
if (typeof option != 'object') {
if (keyField) {
option = items.find(obj => obj[keyField] === option)
} else {
option = items.find(obj => obj === option)
}
}
const title = option ? titleGetter(option) : ''
return title ? title : ''
}
}
renderOption={(props, option) => (
<MenuItem {...props} key={keyGetter(option)} value={keyGetter(option)}>{titleGetter(option)}</MenuItem>
)}
isOptionEqualToValue={(option, value) => keyGetter(option) == value}
value={value}
onChange={(e, nV) => {onChange({target:{value:nV ? keyGetter(nV) : emptyValue}})}}
renderInput={(params) => <TextField {...params} label={label} />}
/>
</>
)}
</FormControl>
);
}
Expand Down
2 changes: 1 addition & 1 deletion modern/src/settings/ComputedAttributePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ const ComputedAttributePage = () => {
</AccordionSummary>
<AccordionDetails className={classes.details}>
<SelectField
value={deviceId || 0}
value={deviceId || null}
onChange={(e) => setDeviceId(Number(e.target.value))}
endpoint="/api/devices"
label={t('sharedDevice')}
Expand Down
4 changes: 2 additions & 2 deletions modern/src/settings/DevicePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const DevicePage = () => {
</AccordionSummary>
<AccordionDetails className={classes.details}>
<SelectField
value={item.groupId || 0}
value={item.groupId || null}
onChange={(event) => setItem({ ...item, groupId: Number(event.target.value) })}
endpoint="/api/groups"
label={t('groupParent')}
Expand Down Expand Up @@ -134,7 +134,7 @@ const DevicePage = () => {
label={t('deviceCategory')}
/>
<SelectField
value={item.calendarId || 0}
value={item.calendarId || null}
onChange={(event) => setItem({ ...item, calendarId: Number(event.target.value) })}
endpoint="/api/calendars"
label={t('sharedCalendar')}
Expand Down
2 changes: 1 addition & 1 deletion modern/src/settings/GeofencePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const GeofencePage = () => {
label={t('sharedDescription')}
/>
<SelectField
value={item.calendarId || 0}
value={item.calendarId || null}
onChange={(event) => setItem({ ...item, calendarId: Number(event.target.value) })}
endpoint="/api/calendars"
label={t('sharedCalendar')}
Expand Down
2 changes: 1 addition & 1 deletion modern/src/settings/GroupPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const GroupPage = () => {
</AccordionSummary>
<AccordionDetails className={classes.details}>
<SelectField
value={item.groupId || 0}
value={item.groupId || null}
onChange={(event) => setItem({ ...item, groupId: Number(event.target.value) })}
endpoint="/api/groups"
label={t('groupParent')}
Expand Down
4 changes: 2 additions & 2 deletions modern/src/settings/PreferencesPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,8 @@ const PreferencesPage = () => {
label={t('devicePrimaryInfo')}
/>
<SelectField
emptyValue=""
value={attributes.deviceSecondary || ''}
emptyValue={null}
value={attributes.deviceSecondary || null}
onChange={(e) => setAttributes({ ...attributes, deviceSecondary: e.target.value })}
data={deviceFields}
titleGetter={(it) => t(it.name)}
Expand Down
5 changes: 3 additions & 2 deletions modern/src/settings/ServerPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,11 @@ const ServerPage = () => {
</Select>
</FormControl>
<SelectField
value={item.attributes.timezone || ''}
emptyValue=""
value={item.attributes.timezone || null}
emptyValue={null}
onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, timezone: e.target.value } })}
endpoint="/api/server/timezones"
keyField={false}
keyGetter={(it) => it}
titleGetter={(it) => it}
label={t('sharedTimezone')}
Expand Down
5 changes: 3 additions & 2 deletions modern/src/settings/UserPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,11 @@ const UserPage = () => {
</Select>
</FormControl>
<SelectField
value={(item.attributes && item.attributes.timezone) || ''}
emptyValue=""
value={(item.attributes && item.attributes.timezone) || null}
emptyValue={null}
onChange={(e) => setItem({ ...item, attributes: { ...item.attributes, timezone: e.target.value } })}
endpoint="/api/server/timezones"
keyField={false}
keyGetter={(it) => it}
titleGetter={(it) => it}
label={t('sharedTimezone')}
Expand Down
3 changes: 2 additions & 1 deletion modern/src/settings/components/BaseCommandView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ const BaseCommandView = ({ deviceId, item, setItem }) => {
return (
<>
<SelectField
value={item.type || ''}
value={item.type || null}
onChange={(e) => setItem({ ...item, type: e.target.value, attributes: {} })}
endpoint={deviceId ? `/api/commands/types?${new URLSearchParams({ deviceId }).toString()}` : '/api/commands/types'}
keyField='type'
keyGetter={(it) => it.type}
titleGetter={(it) => t(prefixString('command', it.type))}
label={t('sharedType')}
Expand Down

0 comments on commit 783eccb

Please sign in to comment.