react-dom#unstable_batchedUpdates JavaScript Examples
The following examples show how to use
react-dom#unstable_batchedUpdates.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.js From react-menu with MIT License | 6 votes |
batchedUpdates = unstable_batchedUpdates || function (callback) {
return callback();
}
Example #2
Source File: utils.js From react-menu with MIT License | 6 votes |
batchedUpdates = unstable_batchedUpdates || ((callback) => callback())
Example #3
Source File: GlobalSelectionSlider.jsx From viv with MIT License | 4 votes |
export default function GlobalSelectionSlider(props) {
const { size, label } = props;
const [selections, setPropertiesForChannel] = useChannelsStore(
store => [store.selections, store.setPropertiesForChannel],
shallow
);
const loader = useLoader();
const globalSelection = useViewerStore(store => store.globalSelection);
const changeSelection = useCallback(
debounce(
(event, newValue) => {
useViewerStore.setState({
isChannelLoading: selections.map(() => true)
});
const newSelections = [...selections].map(sel => ({
...sel,
[label]: newValue
}));
getMultiSelectionStats({
loader,
selections: newSelections,
use3d: false
}).then(({ domains, contrastLimits }) => {
unstable_batchedUpdates(() => {
range(newSelections.length).forEach((channel, j) =>
setPropertiesForChannel(channel, {
domains: domains[j],
contrastLimits: contrastLimits[j]
})
);
});
unstable_batchedUpdates(() => {
useImageSettingsStore.setState({
onViewportLoad: () => {
useImageSettingsStore.setState({
onViewportLoad: () => {}
});
useViewerStore.setState({
isChannelLoading: selections.map(() => false)
});
}
});
range(newSelections.length).forEach((channel, j) =>
setPropertiesForChannel(channel, {
selections: newSelections[j]
})
);
});
});
},
50,
{ trailing: true }
),
[loader, selections]
);
return (
<Grid container direction="row" justify="space-between" alignItems="center">
<Grid item xs={1}>
{label}:
</Grid>
<Grid item xs={11}>
<Slider
value={globalSelection[label]}
onChange={(event, newValue) => {
useViewerStore.setState({
globalSelection: {
...globalSelection,
[label]: newValue
}
});
if (event.type === 'keydown') {
changeSelection(event, newValue);
}
}}
onChangeCommitted={changeSelection}
valueLabelDisplay="auto"
getAriaLabel={() => `${label} slider`}
marks={range(size).map(val => ({ value: val }))}
min={0}
max={size}
orientation="horizontal"
style={{ marginTop: '7px' }}
step={null}
/>
</Grid>
</Grid>
);
}
Example #4
Source File: hooks.js From viv with MIT License | 4 votes |
useImage = (source, history) => {
const [use3d, toggleUse3d, toggleIsOffsetsSnackbarOn] = useViewerStore(
store => [store.use3d, store.toggleUse3d, store.toggleIsOffsetsSnackbarOn],
shallow
);
const [lensEnabled, toggleLensEnabled] = useImageSettingsStore(
store => [store.lensEnabled, store.toggleLensEnabled],
shallow
);
const loader = useLoader();
const metadata = useMetadata();
useEffect(() => {
async function changeLoader() {
// Placeholder
useViewerStore.setState({ isChannelLoading: [true] });
useViewerStore.setState({ isViewerLoading: true });
if (use3d) toggleUse3d();
const { urlOrFile } = source;
const newLoader = await createLoader(
urlOrFile,
toggleIsOffsetsSnackbarOn,
message =>
useViewerStore.setState({
loaderErrorSnackbar: { on: true, message }
})
);
let nextMeta;
let nextLoader;
if (Array.isArray(newLoader)) {
if (newLoader.length > 1) {
nextMeta = newLoader.map(l => l.metadata);
nextLoader = newLoader.map(l => l.data);
} else {
nextMeta = newLoader[0].metadata;
nextLoader = newLoader[0].data;
}
} else {
nextMeta = newLoader.metadata;
nextLoader = newLoader.data;
}
if (nextLoader) {
console.info(
'Metadata (in JSON-like form) for current file being viewed: ',
nextMeta
);
unstable_batchedUpdates(() => {
useChannelsStore.setState({ loader: nextLoader });
useViewerStore.setState({
metadata: nextMeta
});
});
if (use3d) toggleUse3d();
// eslint-disable-next-line no-unused-expressions
history?.push(
typeof urlOrFile === 'string' ? `?image_url=${urlOrFile}` : ''
);
}
}
if (source) changeLoader();
}, [source, history]); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
const changeSettings = async () => {
// Placeholder
useViewerStore.setState({ isChannelLoading: [true] });
useViewerStore.setState({ isViewerLoading: true });
if (use3d) toggleUse3d();
const newSelections = buildDefaultSelection(loader[0]);
const { Channels } = metadata.Pixels;
const channelOptions = Channels.map((c, i) => c.Name ?? `Channel ${i}`);
// Default RGB.
let newContrastLimits = [];
let newDomains = [];
let newColors = [];
const isRgb = guessRgb(metadata);
if (isRgb) {
if (isInterleaved(loader[0].shape)) {
// These don't matter because the data is interleaved.
newContrastLimits = [[0, 255]];
newDomains = [[0, 255]];
newColors = [[255, 0, 0]];
} else {
newContrastLimits = [
[0, 255],
[0, 255],
[0, 255]
];
newDomains = [
[0, 255],
[0, 255],
[0, 255]
];
newColors = [
[255, 0, 0],
[0, 255, 0],
[0, 0, 255]
];
}
if (lensEnabled) {
toggleLensEnabled();
}
useViewerStore.setState({ useColormap: false, useLens: false });
} else {
const stats = await getMultiSelectionStats({
loader,
selections: newSelections,
use3d: false
});
newDomains = stats.domains;
newContrastLimits = stats.contrastLimits;
// If there is only one channel, use white.
newColors =
newDomains.length === 1
? [[255, 255, 255]]
: newDomains.map((_, i) => COLOR_PALLETE[i]);
useViewerStore.setState({
useLens: channelOptions.length !== 1,
useColormap: true
});
}
useChannelsStore.setState({
ids: newDomains.map(() => String(Math.random())),
selections: newSelections,
domains: newDomains,
contrastLimits: newContrastLimits,
colors: newColors,
channelsVisible: newColors.map(() => true)
});
useViewerStore.setState({
isChannelLoading: newSelections.map(i => !i),
isViewerLoading: false,
pixelValues: new Array(newSelections.length).fill(FILL_PIXEL_VALUE),
// Set the global selections (needed for the UI). All selections have the same global selection.
globalSelection: newSelections[0],
channelOptions
});
const [xSlice, ySlice, zSlice] = getBoundingCube(loader);
useImageSettingsStore.setState({
xSlice,
ySlice,
zSlice
});
};
if (metadata) changeSettings();
}, [loader, metadata]); // eslint-disable-line react-hooks/exhaustive-deps
}
Example #5
Source File: Form.js From web-client with Apache License 2.0 | 4 votes |
VulnerabilityForm = ({
isEditForm = false,
vulnerability,
vulnerabilitySetter: setVulnerability,
onFormSubmit
}) => {
const [initialised, setInitialised] = useState(false);
const [projects, setProjects] = useState(null);
const [categories, setCategories] = useState(null);
const [subCategories, setSubCategories] = useState(null);
const [targets, setTargets] = useState(null);
const [useOWASP, setMetrics] = useState(false);
useEffect(() => {
if (initialised) return;
Promise.all([
secureApiFetch(`/projects`, { method: 'GET' }),
secureApiFetch(`/vulnerabilities/categories`, { method: 'GET' }),
])
.then(resp => {
const [respA, respB] = resp;
return Promise.all([respA.json(), respB.json()]);
})
.then(([projects, categories]) => {
const defaultProjectId = projects.length ? projects[0].id : 0;
const projectId = isEditForm ? vulnerability.project_id : defaultProjectId;
setMetrics(isOwaspProject(projects, projectId))
var subcategories = null;
if (vulnerability.parent_category_id) {
secureApiFetch(`/vulnerabilities/categories/${vulnerability.parent_category_id}`, { method: 'GET' })
.then(response => response.json())
.then(json => {
subcategories = json;
})
}
secureApiFetch(`/targets?projectId=${projectId}`, { method: 'GET' })
.then(resp => resp.json())
.then(targets => {
unstable_batchedUpdates(() => {
setProjects(projects);
setCategories(categories);
setTargets(targets);
setVulnerability(prevVulnerability => {
let updatedVulnerability = prevVulnerability;
if (!idExists(projects, prevVulnerability.project_id)) {
updatedVulnerability.project_id = defaultProjectId;
}
if ((!idExists(categories, prevVulnerability.category_id)) && (!idExists(subcategories, prevVulnerability.category_id))) {
updatedVulnerability.category_id = categories[0].id;
}
if (!idExists(targets, vulnerability.target_id)) {
updatedVulnerability.target_id = null;
}
return updatedVulnerability;
})
setInitialised(true);
});
})
});
}, [initialised, isEditForm, setProjects, setCategories, setTargets, setMetrics, setVulnerability, vulnerability.target_id, vulnerability.project_id, vulnerability.parent_category_id, subCategories, setSubCategories]);
useEffect(() => {
if (!initialised) return;
if (vulnerability.parent_category_id) {
secureApiFetch(`/vulnerabilities/categories/${vulnerability.parent_category_id}`, { method: 'GET' })
.then(response => response.json())
.then(json => {
setSubCategories(json);
})
}
const projectId = vulnerability.project_id;
secureApiFetch(`/targets?projectId=${projectId}`, { method: 'GET' })
.then(resp => resp.json())
.then(targets => {
unstable_batchedUpdates(() => {
setTargets(targets);
if (isEditForm) { // Edit
if (!idExists(targets, vulnerability.target_id)) {
setVulnerability(prevVulnerability => {
return { ...prevVulnerability, target_id: 0 }
});
}
}
});
})
}, [initialised, isEditForm, setTargets, setVulnerability, vulnerability.target_id, vulnerability.project_id, vulnerability.parent_category_id]);
const idExists = (elements, id) => {
if (!elements) return false;
for (const el of elements) {
if (el.id === parseInt(id)) return true;
}
return false;
}
const isOwaspProject = (elements, id) => {
let metrics = ProjectVulnerabilityMetrics[0].id;
for (const el of elements) {
if (el.id === parseInt(id)) {
metrics = el.vulnerability_metrics;
}
}
return (ProjectVulnerabilityMetrics[1].id === metrics);
}
const onFormChange = ev => {
const target = ev.target;
const name = target.name;
let value = target.type === 'checkbox' ? target.checked : target.value;
if ('tags' === name) {
value = JSON.stringify(value.split(','));
}
if ('category_id' === name) {
if (value !== '(none)') {
secureApiFetch(`/vulnerabilities/categories/${value}`, { method: 'GET' })
.then(response => response.json())
.then(json => {
setSubCategories(json);
})
setVulnerability({ ...vulnerability, 'parent_category_id': value, [name]: value });
} else {
setVulnerability({ ...vulnerability, 'category_id': null });
}
} else if ('subcategory_id' === name) {
setVulnerability({ ...vulnerability, 'category_id': value });
} else {
setVulnerability({ ...vulnerability, [name]: value });
}
};
return <form onSubmit={onFormSubmit} className="crud">
<Accordion defaultIndex={0} allowToggle allowMultiple>
<AccordionItem index={0}>
<h2>
<AccordionButton>
<Box flex="1" textAlign="left">
Basic information
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<label>Properties
<div>
<Checkbox name="is_template" onChange={onFormChange} isChecked={vulnerability.is_template}>Is template</Checkbox>
</div>
</label>
<label>External ID
<Input type="text" name="external_id" value={vulnerability.external_id || ""} onChange={onFormChange} />
</label>
<label>Summary
<Input type="text" name="summary" value={vulnerability.summary || ""} onChange={onFormChange} required autoFocus />
</label>
<label>Description
<MarkdownEditor name="description" value={vulnerability.description || ""} onChange={onFormChange} />
</label>
<label>External references
<MarkdownEditor name="external_refs" value={vulnerability.external_refs || ""} onChange={onFormChange} />
</label>
<label>Category
<Select name="category_id" value={vulnerability.parent_category_id || ""} onChange={onFormChange} required>
<option>(none)</option>
{categories && categories.map(cat =>
<option key={cat.id} value={cat.id}>{cat.name}</option>
)}
</Select>
</label>
<label>Subcategory
<Select name="subcategory_id" value={vulnerability.category_id || ""} onChange={onFormChange} required>
<option>(none)</option>
{subCategories && subCategories.map(subcat =>
<option key={subcat.id} value={subcat.id}>{subcat.name}</option>
)}
</Select>
</label>
<FormControl id="visibility" isRequired>
<FormLabel>Visibility</FormLabel>
<Select name="visibility" value={vulnerability.visibility || ""} onChange={onFormChange}>
<option value="public">Public</option>
<option value="private">Private</option>
</Select>
<FormHelperText>Private makes this vulnerability not visible to the client.</FormHelperText>
</FormControl>
<label>Risk
<Select name="risk" value={vulnerability.risk || ""} onChange={onFormChange} required>
{Risks.map(risk =>
<option key={risk.id} value={risk.id}>{risk.name}</option>
)}
</Select>
</label>
<label>Tags
<Input type="text" name="tags" onChange={onFormChange} value={vulnerability.tags ? JSON.parse(vulnerability.tags).join(',') : ''} />
</label>
<label>Proof of concept
<MarkdownEditor name="proof_of_concept" value={vulnerability.proof_of_concept || ""} onChange={onFormChange} />
</label>
<label>Impact
<MarkdownEditor name="impact" value={vulnerability.impact || ""} onChange={onFormChange} />
</label>
{
!useOWASP && <>
<label>CVSS score
<Input type="number" step="0.1" min="0" max="10" name="cvss_score" value={vulnerability.cvss_score || ""}
onChange={onFormChange} />
</label>
<label><span><CvssAbbr /> vector</span>
<Input type="text" name="cvss_vector" value={vulnerability.cvss_vector || ""} onChange={onFormChange} placeholder="eg: AV:N/AC:L/Au:S/C:P/I:P/A:N" />
</label>
</>
}
</AccordionPanel>
</AccordionItem>
{useOWASP &&
<AccordionItem>
<h2>
<AccordionButton>
<Box flex="1" textAlign="left">
Owasp Risk Rating calculator
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<label>Owasp Risk Rating</label>
<OwaspRR vulnerability={vulnerability} vulnerabilitySetter={setVulnerability} />
</AccordionPanel>
</AccordionItem>
}
<AccordionItem>
<h2>
<AccordionButton>
<Box flex="1" textAlign="left">
Remediation
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<label>Remediation instructions
<MarkdownEditor name="remediation" value={vulnerability.remediation || ""} onChange={onFormChange} />
</label>
<label>Remediation complexity
<Select name="remediation_complexity" value={vulnerability.remediation_complexity || ""} onChange={onFormChange} required>
{RemediationComplexity.map(complexity =>
<option key={complexity.id} value={complexity.id}>{complexity.name}</option>
)}
</Select>
</label>
<label>Remediation priority
<Select name="remediation_priority" value={vulnerability.remediation_priority || ""} onChange={onFormChange} required>
{RemediationPriority.map(priority =>
<option key={priority.id} value={priority.id}>{priority.name}</option>
)}
</Select>
</label>
</AccordionPanel>
</AccordionItem>
{
!vulnerability.is_template && <AccordionItem>
<h2>
<AccordionButton>
<Box flex="1" textAlign="left">
Relations
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<label>Project
<Select name="project_id" value={vulnerability.project_id || ""} onChange={onFormChange} required>
{projects && projects.map((project, index) =>
<option key={index} value={project.id}>{project.name}</option>
)}
</Select>
</label>
<label>Affected target
<Select name="target_id" value={vulnerability.target_id || ""} onChange={onFormChange}>
<option value="0">(none)</option>
{targets && targets.map((target, index) =>
<option key={index} value={target.id}>{target.name}</option>
)}
</Select>
</label>
</AccordionPanel>
</AccordionItem>
}
</Accordion>
<Primary type="submit">{isEditForm ? "Save" : "Add"}</Primary>
</form >
}