Files
pybricks-code/src/explorer/duplicateFileDialog/DuplicateFileDialog.tsx
T
David Lechner a3e55c828a move useI18n to i18n.ts
Since we are using the react-i18n babel loader plugin, useI18n can only
be used once per file. Also we have to remember to add the istanbul
ignore next comment each time we use it. By moving this to a common
file, it can be easily copied and pasted when a new submodule is
created and we don't have to remember the rules when calling it.
2022-05-21 13:57:58 -05:00

87 lines
3.0 KiB
TypeScript

// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
import { Button, Classes, Dialog } from '@blueprintjs/core';
import React, { useCallback, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import { useFileStorageMetadata } from '../../fileStorage/hooks';
import {
FileNameValidationResult,
validateFileName,
} from '../../pybricksMicropython/lib';
import { useSelector } from '../../reducers';
import FileNameFormGroup from '../fileNameFormGroup/FileNameFormGroup';
import { duplicateFileDialogDidAccept, duplicateFileDialogDidCancel } from './actions';
import { I18nId, useI18n } from './i18n';
const DuplicateFileDialog: React.VFC = () => {
const i18n = useI18n();
const dispatch = useDispatch();
const isOpen = useSelector((s) => s.explorer.duplicateFileDialog.isOpen);
const oldName = useSelector((s) => s.explorer.duplicateFileDialog.fileName);
const [baseName, extension] = oldName.split(/(\.\w+)$/);
const [newName, setNewName] = useState(baseName);
const files = useFileStorageMetadata() ?? [];
const result = validateFileName(
newName,
extension,
files.map((f) => f.path),
);
const inputRef = useRef<HTMLInputElement>(null);
const handleSubmit = useCallback<React.FormEventHandler>(
(e) => {
e.preventDefault();
dispatch(duplicateFileDialogDidAccept(oldName, `${newName}${extension}`));
},
[dispatch, oldName, newName, extension],
);
const handleClose = useCallback(() => {
dispatch(duplicateFileDialogDidCancel());
}, [dispatch]);
return (
<Dialog
title={i18n.translate(I18nId.Title, {
fileName: oldName,
})}
isOpen={isOpen}
onOpening={() => setNewName(baseName)}
onOpened={() => {
inputRef.current?.select();
inputRef.current?.focus();
}}
onClose={handleClose}
>
<form onSubmit={handleSubmit}>
<div className={Classes.DIALOG_BODY}>
<FileNameFormGroup
fileName={newName}
fileExtension={extension}
validationResult={result}
inputRef={inputRef}
onChange={setNewName}
/>
</div>
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button
intent="primary"
disabled={result !== FileNameValidationResult.IsOk}
type="submit"
>
{i18n.translate(I18nId.ActionAccept)}
</Button>
</div>
</div>
</form>
</Dialog>
);
};
export default DuplicateFileDialog;