github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/components/dashboards/inputs/TextInput/index.tsx (about) 1 import { ClearIcon, SubmitIcon } from "../../../../constants/icons"; 2 import { DashboardActions, DashboardDataModeLive } from "../../../../types"; 3 import { registerInputComponent } from "../index"; 4 import { IInput, InputProps } from "../types"; 5 import { useDashboard } from "../../../../hooks/useDashboard"; 6 import { useEffect, useState } from "react"; 7 8 const TextInput = (props: InputProps) => { 9 const { dataMode, dispatch, selectedDashboardInputs } = useDashboard(); 10 const stateValue = selectedDashboardInputs[props.name]; 11 const [value, setValue] = useState<string>(() => { 12 return stateValue || ""; 13 }); 14 const [isDirty, setIsDirty] = useState<boolean>(false); 15 16 const updateValue = (e) => { 17 setValue(e.target.value); 18 setIsDirty(true); 19 }; 20 21 const submit = () => { 22 setIsDirty(false); 23 if (value) { 24 dispatch({ 25 type: DashboardActions.SET_DASHBOARD_INPUT, 26 name: props.name, 27 value, 28 recordInputsHistory: !!stateValue, 29 }); 30 } else { 31 dispatch({ 32 type: DashboardActions.DELETE_DASHBOARD_INPUT, 33 name: props.name, 34 recordInputsHistory: !!stateValue, 35 }); 36 } 37 }; 38 39 const clear = () => { 40 setValue(""); 41 setIsDirty(false); 42 dispatch({ 43 type: DashboardActions.DELETE_DASHBOARD_INPUT, 44 name: props.name, 45 recordInputsHistory: true, 46 }); 47 }; 48 49 useEffect(() => { 50 setValue(stateValue || ""); 51 setIsDirty(false); 52 }, [stateValue]); 53 54 const readOnly = dataMode !== DashboardDataModeLive; 55 56 return ( 57 <div> 58 {props.properties.label && ( 59 <label htmlFor={props.name} className="block mb-1"> 60 {props.properties.label} 61 </label> 62 )} 63 <div className="relative"> 64 <input 65 type="text" 66 name={props.name} 67 id={props.name} 68 className="flex-1 block w-full bg-dashboard-panel rounded-md border border-black-scale-3 pr-8 overflow-x-auto text-sm md:text-base disabled:bg-black-scale-1 focus:ring-0" 69 onChange={updateValue} 70 onKeyPress={(e) => { 71 if (e.key !== "Enter") { 72 return; 73 } 74 submit(); 75 }} 76 placeholder={props.properties.placeholder} 77 readOnly={readOnly} 78 value={value} 79 /> 80 {value && isDirty && !readOnly && ( 81 <div 82 className="absolute inset-y-0 right-0 pr-3 flex items-center cursor-pointer text-foreground-light" 83 onClick={submit} 84 title="Submit" 85 > 86 <SubmitIcon className="h-4 w-4" /> 87 </div> 88 )} 89 {value && !isDirty && !readOnly && ( 90 <div 91 className="absolute inset-y-0 right-0 pr-3 flex items-center cursor-pointer text-foreground-light" 92 onClick={clear} 93 title="Clear" 94 > 95 <ClearIcon className="h-4 w-4" /> 96 </div> 97 )} 98 </div> 99 </div> 100 ); 101 }; 102 103 const definition: IInput = { 104 type: "text", 105 component: TextInput, 106 }; 107 108 registerInputComponent(definition.type, definition); 109 110 export default definition;