diff options
author | Anton Tananaev <anton@traccar.org> | 2022-06-09 16:08:53 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-06-09 16:08:53 -0700 |
commit | 147230408db8afd83e4e90d2958cf8b032f5fbbf (patch) | |
tree | 51edf3d778dd4af61893f01d1190d0547cfb0d26 /modern/src | |
parent | 745f0d345d02ab0032b966be0eb72d3c19844f5a (diff) | |
download | trackermap-web-147230408db8afd83e4e90d2958cf8b032f5fbbf.tar.gz trackermap-web-147230408db8afd83e4e90d2958cf8b032f5fbbf.tar.bz2 trackermap-web-147230408db8afd83e4e90d2958cf8b032f5fbbf.zip |
Avoid preloading links
Diffstat (limited to 'modern/src')
-rw-r--r-- | modern/src/common/components/LinkField.js | 111 |
1 files changed, 64 insertions, 47 deletions
diff --git a/modern/src/common/components/LinkField.js b/modern/src/common/components/LinkField.js index 3b38460d..22ede201 100644 --- a/modern/src/common/components/LinkField.js +++ b/modern/src/common/components/LinkField.js @@ -1,5 +1,5 @@ import { - FormControl, InputLabel, MenuItem, Select, + FormControl, InputLabel, MenuItem, Select, Skeleton, } from '@mui/material'; import React, { useState } from 'react'; import { useEffectAsync } from '../../reactHelper'; @@ -14,27 +14,33 @@ const LinkField = ({ keyGetter = (item) => item.id, titleGetter = (item) => item.name, }) => { + const [active, setActive] = useState(false); + const [open, setOpen] = useState(false); const [items, setItems] = useState(); const [linked, setLinked] = useState(); useEffectAsync(async () => { - const response = await fetch(endpointAll); - if (response.ok) { - setItems(await response.json()); - } else { - throw Error(await response.text()); + if (active) { + const response = await fetch(endpointAll); + if (response.ok) { + setItems(await response.json()); + } else { + throw Error(await response.text()); + } } - }, []); + }, [active]); useEffectAsync(async () => { - const response = await fetch(endpointLinked); - if (response.ok) { - const data = await response.json(); - setLinked(data.map((it) => it.id)); - } else { - throw Error(await response.text()); + if (active) { + const response = await fetch(endpointLinked); + if (response.ok) { + const data = await response.json(); + setLinked(data.map((it) => it.id)); + } else { + throw Error(await response.text()); + } } - }, []); + }, [active]); const createBody = (linkId) => { const body = {}; @@ -46,43 +52,54 @@ const LinkField = ({ const onChange = async (event) => { const oldValue = linked; const newValue = event.target.value; - const results = []; - newValue.filter((it) => !oldValue.includes(it)).forEach((added) => { - results.push(fetch('/api/permissions', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(createBody(added)), - })); - }); - oldValue.filter((it) => !newValue.includes(it)).forEach((removed) => { - results.push(fetch('/api/permissions', { - method: 'DELETE', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(createBody(removed)), - })); - }); - await Promise.all(results); - setLinked(newValue); + if (!newValue.find((it) => it < 0)) { + const results = []; + newValue.filter((it) => !oldValue.includes(it)).forEach((added) => { + results.push(fetch('/api/permissions', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(createBody(added)), + })); + }); + oldValue.filter((it) => !newValue.includes(it)).forEach((removed) => { + results.push(fetch('/api/permissions', { + method: 'DELETE', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(createBody(removed)), + })); + }); + await Promise.all(results); + setLinked(newValue); + } }; - if (items && linked) { - return ( - <FormControl> - <InputLabel>{label}</InputLabel> - <Select - label={label} - multiple - value={linked} - onChange={onChange} - > - {items.map((item) => ( + return ( + <FormControl> + <InputLabel>{label}</InputLabel> + <Select + label={label} + open={open} + onOpen={() => { + setActive(true); + setOpen(true); + }} + onClose={() => setOpen(false)} + value={linked || []} + onChange={onChange} + multiple + > + {items && linked + ? items.map((item) => ( <MenuItem key={keyGetter(item)} value={keyGetter(item)}>{titleGetter(item)}</MenuItem> + )) + : [...Array(3)].map((_, i) => ( + <MenuItem key={-i - 1} value={-i - 1}> + <Skeleton variant="text" width={`${Math.floor(Math.random() * 30 + 30)}%`} /> + </MenuItem> ))} - </Select> - </FormControl> - ); - } - return null; + </Select> + </FormControl> + ); }; export default LinkField; |