@material-ui/core#debounce TypeScript Examples

The following examples show how to use @material-ui/core#debounce. 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: PanelSearch.tsx    From clearflask with Apache License 2.0 6 votes vote down vote up
readonly updateSearchText = debounce(
    (searchText?: string) => {
      if (!isFilterControllable(this.props.explorer, PostFilterType.Search)) return;
      this.props.onSearchChanged({
        ...this.props.search,
        searchText: searchText,
      });
    },
    SearchTypeDebounceTime);
Example #2
Source File: rpc.ts    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
Rpc = {
  sendNativeTransaction,
  sendBzzTransaction,
  _eth_getBalance: eth_getBalance,
  _eth_getBalanceERC20: eth_getBalanceERC20,
  eth_getBalance: debounce(eth_getBalance, 1_000),
  eth_getBalanceERC20: debounce(eth_getBalanceERC20, 1_000),
  eth_getBlockByNumber,
}
Example #3
Source File: use-fuse.ts    From mtcute with GNU Lesser General Public License v3.0 6 votes vote down vote up
export function useFuse<T>(
    items: T[],
    options: Fuse.IFuseOptions<T>,
    searchOptions: Fuse.FuseSearchOptions,
    customFilter?: (it: T) => boolean
) {
    const [query, updateQuery] = useState('')

    const fuse = useMemo(() => new Fuse(items, options), [items, options])

    const hits = useMemo(() => {
        if (!query) return []
        let res = fuse.search(query, searchOptions)
        if (customFilter) res = res.filter((it) => customFilter(it.item))
        return res
    }, [
        fuse,
        query,
        options,
        searchOptions,
        customFilter
    ])

    const setQuery = useCallback(debounce(updateQuery, 100), [])

    const onSearch = useCallback(
        (e: ChangeEvent<HTMLInputElement>) => setQuery(e.target.value),
        []
    )

    return {
        hits,
        onSearch,
        query,
        setQuery
    }
}
Example #4
Source File: Card.tsx    From neodash with Apache License 2.0 4 votes vote down vote up
NeoCard = ({
    index, // index of the card. 
    report, // state of the card, retrieved based on card index.
    editable, // whether the card is editable.
    database, // the neo4j database that the card is running against.
    globalParameters, // Query parameters that are globally set for the entire dashboard.
    dashboardSettings, // Dictionary of settings for the entire dashboard.
    onRemovePressed, // action to take when the card is removed. (passed from parent)
    onClonePressed, // action to take when user presses the clone button
    onReportHelpButtonPressed, // action to take when someone clicks the 'help' button in the report settings.
    onTitleUpdate, // action to take when the card title is updated.
    onTypeUpdate, // action to take when the card report type is updated.
    onFieldsUpdate, // action to take when the set of returned query fields is updated.
    onQueryUpdate, // action to take when the card query is updated.
    onRefreshRateUpdate, // action to take when the card refresh rate is updated.
    onReportSettingUpdate, // action to take when an advanced report setting is updated.
    onSelectionUpdate, // action to take when the selected visualization fields are updated.
    onGlobalParameterUpdate, // action to take when a report updates a dashboard parameter.
    onToggleCardSettings, // action to take when the card settings button is clicked.
    onToggleReportSettings, // action to take when the report settings (advanced settings) button is clicked.
    onCreateNotification // action to take when an (error) notification is created.
}) => {
   
    const [settingsOpen, setSettingsOpen] = React.useState(false);
    const debouncedOnToggleCardSettings = useCallback(
        debounce(onToggleCardSettings, 500),
        [],
    );
    const [collapseTimeout, setCollapseTimeout] = React.useState(report.collapseTimeout);

    const { observe, unobserve, width, height, entry } = useDimensions({
        onResize: ({ observe, unobserve, width, height, entry }) => {
            // Triggered whenever the size of the target is changed...
            unobserve(); // To stop observing the current target element
            observe(); // To re-start observing the current target element
        },
    });

    const [expanded, setExpanded] = useState(false);
    const onToggleCardExpand = () => {
        // When we re-minimize a card, close the settings to avoid position issues.
        if(expanded && settingsOpen){
            onToggleCardSettings(index, false);
        }
        setExpanded(!expanded);
    }

    const [active, setActive] = React.useState(report.settings && report.settings.autorun !== undefined ? report.settings.autorun : true);

    useEffect(() => {
        if (!report.settingsOpen) {
            setActive(report.settings && report.settings.autorun !== undefined ? report.settings.autorun : true);
        }
    }, [report.query])


    useEffect(() => {
        setSettingsOpen(report.settingsOpen);
    }, [report.settingsOpen])

    useEffect(() => {
        setCollapseTimeout(report.collapseTimeout);
    }, [report.collapseTimeout])

    // TODO - get rid of some of the props-drilling here...
    const component = <div style={{ height: "100%" }} ref={observe}>
        {/* The front of the card, referred to as the 'view' */}
        <Collapse disableStrictModeCompat in={!settingsOpen} timeout={collapseTimeout} style={{ height: "100%" }}>
            <Card style={{ height: "100%" }}>
                <NeoCardView
                    settingsOpen={settingsOpen}
                    editable={editable}
                    dashboardSettings={dashboardSettings}
                    settings={report.settings ? report.settings : {}}
                    type={report.type}
                    database={database}
                    active={active}
                    setActive={setActive}
                    query={report.query}
                    globalParameters={globalParameters}
                    fields={report.fields ? report.fields : []}
                    refreshRate={report.refreshRate}
                    selection={report.selection}
                    widthPx={width}
                    heightPx={height}
                    title={report.title}
                    expanded={expanded}
                    onToggleCardExpand={onToggleCardExpand}
                    onGlobalParameterUpdate={onGlobalParameterUpdate}
                    onSelectionUpdate={(selectable, field) => onSelectionUpdate(index, selectable, field)}
                    onTitleUpdate={(title) => onTitleUpdate(index, title)}
                    onFieldsUpdate={(fields) => onFieldsUpdate(index, fields)}
                    onToggleCardSettings={() => {
                        setSettingsOpen(true);
                        setCollapseTimeout("auto");
                        debouncedOnToggleCardSettings(index, true)
                    }} />
            </Card>
        </Collapse>
        {/* The back of the card, referred to as the 'settings' */}
        <Collapse disableStrictModeCompat in={settingsOpen} timeout={collapseTimeout} >
            <Card style={{ height: "100%" }}>
                <NeoCardSettings
                    settingsOpen={settingsOpen}
                    query={report.query}
                    database={database}
                    width={report.width}
                    height={report.height}
                    widthPx={width}
                    heightPx={height}
                    fields={report.fields}
                    type={report.type}
                    refreshRate={report.refreshRate}
                    expanded={expanded}
                    dashboardSettings={dashboardSettings}
                    onToggleCardExpand={onToggleCardExpand}
                    setActive={setActive}
                    reportSettings={report.settings}
                    reportSettingsOpen={report.advancedSettingsOpen}
                    onQueryUpdate={(query) => onQueryUpdate(index, query)}
                    onRefreshRateUpdate={(rate) => onRefreshRateUpdate(index, rate)}
                    onReportSettingUpdate={(setting, value) => onReportSettingUpdate(index, setting, value)}
                    onTypeUpdate={(type) => onTypeUpdate(index, type)}
                    onReportHelpButtonPressed={() => onReportHelpButtonPressed()}
                    onRemovePressed={() => onRemovePressed(index)}
                    onClonePressed={() => onClonePressed(index)}
                    onCreateNotification={(title, message) => onCreateNotification(title, message)}
                    onToggleCardSettings={() => {
                        setSettingsOpen(false);
                        setCollapseTimeout("auto");
                        debouncedOnToggleCardSettings(index, false);
                    }}
                    onToggleReportSettings={() => onToggleReportSettings(index)} />
            </Card>
        </Collapse>
    </div>;

    // If the card is viewed in fullscreen, wrap it in a dialog.
    // TODO - this causes a re-render (and therefore, a re-run of the report)
    // Look into React Portals: https://stackoverflow.com/questions/61432878/how-to-render-child-component-outside-of-its-parent-component-dom-hierarchy
    if (expanded) {
        return <Dialog maxWidth={"xl"} open={expanded} aria-labelledby="form-dialog-title">
            <DialogContent style={{ width: Math.min(1920, document.documentElement.clientWidth - 64), height: document.documentElement.clientHeight }} >
                {component}
            </DialogContent>
        </Dialog>
    }
    return component;
}
Example #5
Source File: CardSettingsContentPropertySelect.tsx    From neodash with Apache License 2.0 4 votes vote down vote up
NeoCardSettingsContentPropertySelect = ({ type, database, settings, onReportSettingUpdate, onQueryUpdate }) => {
    const { driver } = useContext<Neo4jContextState>(Neo4jContext);
    if (!driver) throw new Error('`driver` not defined. Have you added it into your app as <Neo4jContext.Provider value={{driver}}> ?')

    const debouncedRunCypherQuery = useCallback(
        debounce(runCypherQuery, RUN_QUERY_DELAY_MS),
        [],
    );

    const manualPropertyNameSpecification = settings['manualPropertyNameSpecification'];
    const [labelInputText, setLabelInputText] = React.useState(settings['entityType']);
    const [labelRecords, setLabelRecords] = React.useState([]);
    const [propertyInputText, setPropertyInputText] = React.useState(settings['propertyType']);
    const [propertyRecords, setPropertyRecords] = React.useState([]);
    var parameterName = settings['parameterName'];

    if (settings["type"] == undefined) {
        onReportSettingUpdate("type", "Node Property");
    }
    if (!parameterName && settings['entityType'] && settings['propertyType']) {
        const id = settings['id'] ? settings['id'] : "";
        onReportSettingUpdate("parameterName", "neodash_" + (settings['entityType'] + "_" + settings['propertyType'] + (id == "" || id.startsWith("_") ? id : "_" + id)).toLowerCase().replaceAll(" ", "_").replaceAll("-", "_"));
    }
    // Define query callback to allow reports to get extra data on interactions.
    const queryCallback = useCallback(
        (query, parameters, setRecords) => {
            debouncedRunCypherQuery(driver, database, query, parameters, {}, [], 10,
                (status) => { status == QueryStatus.NO_DATA ? setRecords([]) : null },
                (result => setRecords(result)),
                () => { return }, false,
                false, false,
                [], [], [], [], null);
        },
        [],
    );

    function handleParameterTypeUpdate(newValue) {
        onReportSettingUpdate('entityType', undefined);
        onReportSettingUpdate('propertyType', undefined);
        onReportSettingUpdate('id', undefined);
        onReportSettingUpdate('parameterName', undefined);
        onReportSettingUpdate("type", newValue);
    }

    function handleNodeLabelSelectionUpdate(newValue) {
        setPropertyInputText("");
        onReportSettingUpdate('entityType', newValue);
        onReportSettingUpdate('propertyType', undefined);
        onReportSettingUpdate('parameterName', undefined);
    }

    function handleFreeTextNameSelectionUpdate(newValue) {
        if (newValue) {
            const new_parameter_name = ("neodash_" +  newValue).toLowerCase().replaceAll(" ", "_").replaceAll("-", "_");
            handleReportQueryUpdate(new_parameter_name, newValue, undefined);
        } else {
            onReportSettingUpdate('parameterName', undefined);
        }
    }

    function handlePropertyNameSelectionUpdate(newValue) {
        onReportSettingUpdate('propertyType', newValue);
        if (newValue && settings['entityType']) {
            const id = settings['id'] ? settings['id'] : "";
            const new_parameter_name = "neodash_" + (settings['entityType'] + "_" + newValue + (id == "" || id.startsWith("_") ? id : "_" + id)).toLowerCase().replaceAll(" ", "_").replaceAll("-", "_");
            handleReportQueryUpdate(new_parameter_name, settings['entityType'], newValue);
        } else {
            onReportSettingUpdate('parameterName', undefined);
        }
    }

    function handleIdSelectionUpdate(value) {
        const newValue = value ? value : "";
        onReportSettingUpdate('id', "" + newValue);
        if (settings['propertyType'] && settings['entityType']) {
            const id = value ? "_" + value : "";
            const new_parameter_name = "neodash_" + (settings['entityType'] + "_" + settings['propertyType'] + (id == "" || id.startsWith("_") ? id : "_" + id)).toLowerCase().replaceAll(" ", "_").replaceAll("-", "_");
            handleReportQueryUpdate(new_parameter_name, settings['entityType'], settings['propertyType']);
        }
    }

    function handleReportQueryUpdate(new_parameter_name, entityType, propertyType) {
        // Set query based on whether we are selecting a node or relationship property.
        onReportSettingUpdate('parameterName', new_parameter_name);
        if (settings['type'] == "Node Property") {
            const newQuery = "MATCH (n:`" + entityType + "`) \nWHERE toLower(toString(n.`" + propertyType + "`)) CONTAINS toLower($input) \nRETURN DISTINCT n.`" + propertyType + "` as value LIMIT 5";
            onQueryUpdate(newQuery);
        } else if (settings['type'] == "Relationship Property"){
            const newQuery = "MATCH ()-[n:`" + entityType + "`]->() \nWHERE toLower(toString(n.`" + propertyType + "`)) CONTAINS toLower($input) \nRETURN DISTINCT n.`" + propertyType + "` as value LIMIT 5";
            onQueryUpdate(newQuery);
        } else {
            const newQuery = "RETURN true";
            onQueryUpdate(newQuery);
        }
    }

    const parameterSelectTypes = ["Node Property", "Relationship Property", "Free Text"]

    return <div>
        <p style={{ color: "grey", fontSize: 12, paddingLeft: "5px", border: "1px solid lightgrey", marginTop: "0px" }}>
            {REPORT_TYPES[type].helperText}
        </p>
        <TextField select={true} autoFocus id="type" value={settings["type"] ? settings["type"] : "Node Property"}
            onChange={(e) => {
                handleParameterTypeUpdate(e.target.value);
            }}
            style={{ width: "25%" }} label="Selection Type"
            type="text"
            style={{ width: 335, marginLeft: "5px", marginTop: "0px" }}>
            {parameterSelectTypes.map((option) => (
                <MenuItem key={option} value={option}>
                    {option}
                </MenuItem>
            ))}
        </TextField>

        {settings.type == "Free Text" ?
          <NeoField
            label={"Name"} 
            key={"freetext"}
            value={settings["entityType"] ? settings["entityType"] : ""}
            defaultValue={""}
            placeholder={"Enter a parameter name here..."}
            style={{ width: 335, marginLeft: "5px", marginTop: "0px" }}
            onChange={(value) => {
                setLabelInputText(value);
                handleNodeLabelSelectionUpdate(value);
                handleFreeTextNameSelectionUpdate(value);
            }}
            />
            :
            <>
                <Autocomplete
                    id="autocomplete-label-type"
                    options={manualPropertyNameSpecification ? [settings['entityType']] : labelRecords.map(r => r["_fields"] ? r["_fields"][0] : "(no data)")}
                    getOptionLabel={(option) => option ? option : ""}
                    style={{ width: 335, marginLeft: "5px", marginTop: "5px" }}
                    inputValue={labelInputText}
                    onInputChange={(event, value) => {
                        setLabelInputText(value);
                        if (manualPropertyNameSpecification) {
                            handleNodeLabelSelectionUpdate(value);
                        } else {
                            if (settings["type"] == "Node Property") {
                                queryCallback("CALL db.labels() YIELD label WITH label as nodeLabel WHERE toLower(nodeLabel) CONTAINS toLower($input) RETURN DISTINCT nodeLabel LIMIT 5", { input: value }, setLabelRecords);
                            } else {
                                queryCallback("CALL db.relationshipTypes() YIELD relationshipType WITH relationshipType as relType WHERE toLower(relType) CONTAINS toLower($input) RETURN DISTINCT relType LIMIT 5", { input: value }, setLabelRecords);
                            }
                        }
                    }}
                    value={settings['entityType'] ? settings['entityType'] : undefined}
                    onChange={(event, newValue) => handleNodeLabelSelectionUpdate(newValue)}
                    renderInput={(params) => <TextField {...params} placeholder="Start typing..." InputLabelProps={{ shrink: true }} label={settings["type"] == "Node Property" ? "Node Label" : "Relationship Type"} />}
                />
                {/* Draw the property name & id selectors only after a label/type has been selected. */}
                {settings['entityType'] ?
                    <>
                        <Autocomplete
                            id="autocomplete-property"
                            options={manualPropertyNameSpecification ? [settings['propertyType']] : propertyRecords.map(r => r["_fields"] ? r["_fields"][0] : "(no data)")}
                            getOptionLabel={(option) => option ? option : ""}
                            style={{ display: "inline-block", width: 185, marginLeft: "5px", marginTop: "5px" }}
                            inputValue={propertyInputText}
                            onInputChange={(event, value) => {
                                setPropertyInputText(value);
                                if (manualPropertyNameSpecification) {
                                    handlePropertyNameSelectionUpdate(value);
                                } else {
                                    queryCallback("CALL db.propertyKeys() YIELD propertyKey as propertyName WITH propertyName WHERE toLower(propertyName) CONTAINS toLower($input) RETURN DISTINCT propertyName LIMIT 5", { input: value }, setPropertyRecords);
                                }
                            }}
                            value={settings['propertyType']}
                            onChange={(event, newValue) => handlePropertyNameSelectionUpdate(newValue)}
                            renderInput={(params) => <TextField {...params} placeholder="Start typing..." InputLabelProps={{ shrink: true }} label={"Property Name"} />}
                        />
                        <NeoField placeholder='number'
                            label="Number (optional)" disabled={!settings['propertyType']} value={settings['id']}
                            style={{ width: "135px", marginTop: "5px", marginLeft: "10px" }}
                            onChange={(value) => {
                                handleIdSelectionUpdate(value);
                            }} />
                    </> : <></>}
            </>}
        {parameterName ? <p>Use <b>${parameterName}</b> in a query to use the parameter.</p> : <></>}
    </div>;
}
Example #6
Source File: ParameterSelectionChart.tsx    From neodash with Apache License 2.0 4 votes vote down vote up
NeoParameterSelectionChart = (props: ChartProps) => {

    useEffect(() => {
        debouncedQueryCallback && debouncedQueryCallback(query, { input: inputText }, setExtraRecords);
    }, [inputText, query]);

    const records = props.records;
    const query = records[0]["input"] ? records[0]["input"] : undefined;
    const parameter = props.settings && props.settings["parameterName"] ? props.settings["parameterName"] : undefined;
    const type = props.settings && props.settings["type"] ? props.settings["type"] : undefined;
    const suggestionsUpdateTimeout = props.settings && props.settings["suggestionsUpdateTimeout"] ? props.settings["suggestionsUpdateTimeout"] : 250;
    const setParameterTimeout = props.settings && props.settings["setParameterTimeout"] ? props.settings["setParameterTimeout"] : 1000;
    
    const debouncedQueryCallback = useCallback(
        debounce(props.queryCallback, suggestionsUpdateTimeout),
        [],
    );

    const debouncedSetGlobalParameter = useCallback(
        debounce(props.setGlobalParameter, setParameterTimeout),
        [],
    );

   
    const currentValue = (props.getGlobalParameter && props.getGlobalParameter(parameter)) ? props.getGlobalParameter(parameter) : "";
    const [extraRecords, setExtraRecords] = React.useState([]);
    const [inputText, setInputText] = React.useState(currentValue);
    const [value, setValue] = React.useState(currentValue);

    // In case the components gets (re)loaded with a different/non-existing selected parameter, set the text to the current global parameter value.
    if (query && value != currentValue && currentValue != inputText) {
        setValue(currentValue);
        setInputText(currentValue);
        setExtraRecords([]);
    }
    if (!query || query.trim().length == 0) {
        return <p style={{ margin: "15px" }}>No selection specified. Open up the report settings and choose a node label and property.</p>
    }

    const label = props.settings && props.settings["entityType"] ? props.settings["entityType"] : "";
    const property = props.settings && props.settings["propertyType"] ? props.settings["propertyType"] : "";
    const settings = (props.settings) ? props.settings : {};
    const helperText = settings.helperText;
    const clearParameterOnFieldClear = settings.clearParameterOnFieldClear;

    return <div>
        {type == "Free Text" ?
            <>
                <NeoField
                    key={"freetext"}
                    label={helperText ? helperText : label + " " + property}
                    defaultValue={""}
                    value={value}
                    variant="outlined"
                    placeholder={"Enter text here..."}
                    style={{ maxWidth: "calc(100% - 30px)", marginLeft: "15px", marginTop: "5px" }}
                    onChange={(newValue) => {
                        // TODO: i want this to be a proper wait instead of triggering on the first character.
                        if (newValue == null && clearParameterOnFieldClear) {
                            setValue("");
                            debouncedSetGlobalParameter(parameter, undefined);
                        } else {
                            setValue(newValue);
                            debouncedSetGlobalParameter(parameter, newValue);
                        }
                    }}
                />
                {value !== currentValue ? <CircularProgress size={26} style={{marginTop: "20px", marginLeft: "5px"}} /> : <></>}
            </>
            :
            <Autocomplete
                id="autocomplete"
                options={extraRecords.map(r => r["_fields"] && r["_fields"][0] !== null ? r["_fields"][0] : "(no data)").sort()}
                getOptionLabel={(option) => option ? option.toString() : ""}
                style={{ maxWidth: "calc(100% - 30px)",  marginLeft: "15px", marginTop: "5px" }}
                inputValue={inputText}
                onInputChange={(event, value) => {
                    setInputText("" + value);
                    debouncedQueryCallback(query, { input: ""+value }, setExtraRecords);
                }}
                getOptionSelected={(option, value) => (option && option.toString()) === (value && value.toString())}
                value={value ? value.toString() : "" + currentValue}
                onChange={(event, newValue) => {
                    setValue(newValue);
                    setInputText("" + newValue);

                    if (newValue && newValue["low"]) {
                        newValue = newValue["low"];
                    }
                    if (newValue == null && clearParameterOnFieldClear) {
                        props.setGlobalParameter(parameter, undefined);
                    } else {
                        props.setGlobalParameter(parameter, newValue);
                    }
                }}
                renderInput={(params) => <TextField {...params} InputLabelProps={{ shrink: true }} 
                placeholder="Start typing..." 
                label={helperText ? helperText : label + " " + property} variant="outlined" />}
            />
        }
    </div>
}