mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 17:45:22 +00:00
explorer: implement duplicate file feature
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
import { Button, Classes, Dialog } from '@blueprintjs/core';
|
||||
import { useI18n } from '@shopify/react-i18n';
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import {
|
||||
FileNameValidationResult,
|
||||
validateFileName,
|
||||
} from '../../pybricksMicropython/lib';
|
||||
import { useSelector } from '../../reducers';
|
||||
import FileNameFormGroup from '../fileNameFormGroup/FileNameFormGroup';
|
||||
import { duplicateFileDialogDidAccept, duplicateFileDialogDidCancel } from './actions';
|
||||
import { I18nId } from './i18n';
|
||||
|
||||
const DuplicateFileDialog: React.VFC = () => {
|
||||
// istanbul ignore next: babel-loader rewrites this line
|
||||
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 = useSelector((s) => s.explorer.files);
|
||||
const result = validateFileName(
|
||||
newName,
|
||||
extension,
|
||||
files.map((f) => f.name),
|
||||
);
|
||||
|
||||
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;
|
||||
Reference in New Issue
Block a user