({
size = "sm",
disabled = false,
supportFormats,
supportPassword = false,
viewMode,
tooltip,
text,
validate,
maximumExportCount = Number.MAX_VALUE,
formContent,
onExport,
className,
}: DataExportButtonProps)
| 180 | * selecting a format opens a small Dialog to capture an optional password. |
| 181 | */ |
| 182 | export function DataExportButton({ |
| 183 | size = "sm", |
| 184 | disabled = false, |
| 185 | supportFormats, |
| 186 | supportPassword = false, |
| 187 | viewMode, |
| 188 | tooltip, |
| 189 | text, |
| 190 | validate, |
| 191 | maximumExportCount = Number.MAX_VALUE, |
| 192 | formContent, |
| 193 | onExport, |
| 194 | className, |
| 195 | }: DataExportButtonProps) { |
| 196 | const { t } = useTranslation(); |
| 197 | |
| 198 | const [isRequesting, setIsRequesting] = useState(false); |
| 199 | const [showDrawer, setShowDrawer] = useState(false); |
| 200 | const [showPasswordDialog, setShowPasswordDialog] = useState(false); |
| 201 | |
| 202 | const presetMax = useMemo( |
| 203 | () => computeMaximumPreset(maximumExportCount), |
| 204 | [maximumExportCount] |
| 205 | ); |
| 206 | const defaultLimit = useMemo(() => Math.min(presetMax, 1000), [presetMax]); |
| 207 | |
| 208 | const [limit, setLimit] = useState<number>(defaultLimit); |
| 209 | const [format, setFormat] = useState<ExportFormat>(supportFormats[0]); |
| 210 | const [password, setPassword] = useState(""); |
| 211 | |
| 212 | const resetForm = useCallback(() => { |
| 213 | setLimit(defaultLimit); |
| 214 | setFormat(supportFormats[0]); |
| 215 | setPassword(""); |
| 216 | }, [defaultLimit, supportFormats]); |
| 217 | |
| 218 | // Reset form whenever the drawer transitions to OPEN. Depending on |
| 219 | // `resetForm` here would re-fire the reset on every parent re-render |
| 220 | // because `supportFormats` typically arrives as a fresh inline array |
| 221 | // (e.g. `supportFormats={[CSV, JSON, SQL, XLSX]}` from |
| 222 | // `SingleResultView`), which churns `resetForm`'s identity and would |
| 223 | // clobber the user's just-changed `limit` / `format` / `password`. |
| 224 | // Drive the reset off `showDrawer` alone via a ref to the latest |
| 225 | // `resetForm`. |
| 226 | const resetFormRef = useRef(resetForm); |
| 227 | resetFormRef.current = resetForm; |
| 228 | useEffect(() => { |
| 229 | if (showDrawer) { |
| 230 | resetFormRef.current(); |
| 231 | } |
| 232 | }, [showDrawer]); |
| 233 | |
| 234 | // Clear password each time the password dialog opens. |
| 235 | useEffect(() => { |
| 236 | if (showPasswordDialog) { |
| 237 | setPassword(""); |
| 238 | } |
| 239 | }, [showPasswordDialog]); |
nothing calls this directly
no test coverage detected