mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-14 10:35:11 +00:00
explorer/newFileWizard: add empty file option
Fixes: https://github.com/pybricks/pybricks-code/issues/771
This commit is contained in:
committed by
David Lechner
parent
7810a8ee87
commit
ede6f80f49
@@ -16,13 +16,20 @@ const HubIcon: React.VoidFunctionComponent<HubIconProps> = ({ url, label }) => {
|
||||
return <img src={url.toString()} width={64} height={64} title={label} />;
|
||||
};
|
||||
|
||||
export const HubPicker: React.VoidFunctionComponent = () => {
|
||||
type HubPickerProps = {
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const HubPicker: React.VoidFunctionComponent<HubPickerProps> = ({
|
||||
disabled,
|
||||
}) => {
|
||||
const [selectedHub, setSelectedHub] = useHubPickerSelectedHub();
|
||||
|
||||
return (
|
||||
<RadioGroup
|
||||
className="pb-hub-picker"
|
||||
selectedValue={selectedHub}
|
||||
disabled={disabled}
|
||||
onChange={(e) => setSelectedHub(e.currentTarget.value as Hub)}
|
||||
>
|
||||
<Radio value={Hub.Move}>
|
||||
|
||||
@@ -11,5 +11,9 @@
|
||||
.#{bp.$ns}-radio {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&.#{bp.$ns}-disabled img {
|
||||
opacity: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +337,9 @@ const templateSnippets: Array<
|
||||
* Gets the template text for a Pybricks MicroPython file.
|
||||
* @param hub The hub label.
|
||||
*/
|
||||
export function getPybricksMicroPythonFileTemplate(hub: HubLabel): string | undefined {
|
||||
export function getPybricksMicroPythonFileTemplate(
|
||||
hub: HubLabel | undefined,
|
||||
): string | undefined {
|
||||
return templateSnippets.find((t) => t.label === hub)?.insertText;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
import { Button, Classes, Dialog, FormGroup } from '@blueprintjs/core';
|
||||
import { Button, Classes, Dialog, FormGroup, Switch } from '@blueprintjs/core';
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import { useId } from 'react-aria';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useLocalStorage } from 'usehooks-ts';
|
||||
import { HubPicker } from '../../components/hubPicker/HubPicker';
|
||||
import { useHubPickerSelectedHub } from '../../components/hubPicker/hooks';
|
||||
import { useFileStorageMetadata } from '../../fileStorage/hooks';
|
||||
@@ -22,6 +23,10 @@ const NewFileWizard: React.VoidFunctionComponent = () => {
|
||||
const i18n = useI18n();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [emptyFile, setEmptyFile] = useLocalStorage(
|
||||
'explorer.newFileWizard.emptyFile',
|
||||
false,
|
||||
);
|
||||
const isOpen = useSelector((s) => s.explorer.newFileWizard.isOpen);
|
||||
const [fileName, setFileName] = useState('');
|
||||
const files = useFileStorageMetadata() ?? [];
|
||||
@@ -37,9 +42,15 @@ const NewFileWizard: React.VoidFunctionComponent = () => {
|
||||
const handleSubmit = useCallback<React.FormEventHandler>(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
dispatch(newFileWizardDidAccept(fileName, pythonFileExtension, hubType));
|
||||
dispatch(
|
||||
newFileWizardDidAccept(
|
||||
fileName,
|
||||
pythonFileExtension,
|
||||
emptyFile ? undefined : hubType,
|
||||
),
|
||||
);
|
||||
},
|
||||
[dispatch, fileName, pythonFileExtension, hubType],
|
||||
[dispatch, fileName, pythonFileExtension, hubType, emptyFile],
|
||||
);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
@@ -66,9 +77,20 @@ const NewFileWizard: React.VoidFunctionComponent = () => {
|
||||
inputRef={fileNameInputRef}
|
||||
onChange={setFileName}
|
||||
/>
|
||||
<FormGroup label={i18n.translate('smartHub.label')}>
|
||||
<HubPicker />
|
||||
<FormGroup
|
||||
label={i18n.translate('template.label')}
|
||||
disabled={emptyFile}
|
||||
>
|
||||
<HubPicker disabled={emptyFile} />
|
||||
</FormGroup>
|
||||
<Switch
|
||||
checked={emptyFile}
|
||||
onChange={(e) =>
|
||||
setEmptyFile((e.target as HTMLInputElement).checked)
|
||||
}
|
||||
>
|
||||
{i18n.translate('emptyFile.label')}
|
||||
</Switch>
|
||||
</div>
|
||||
<div className={Classes.DIALOG_FOOTER}>
|
||||
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
|
||||
|
||||
@@ -20,10 +20,14 @@ export const newFileWizardShow = createAction(() => ({
|
||||
* Indicates that the use accepted the new file wizard dialog.
|
||||
* @param fileName The user-provided file name.
|
||||
* @param fileExtension The user-provided file extension.
|
||||
* @param hubType The user-provided hub type.
|
||||
* @param hubType The user-provided hub type or undefined for an empty file.
|
||||
*/
|
||||
export const newFileWizardDidAccept = createAction(
|
||||
(fileName: string, fileExtension: SupportedFileExtension, hubType: Hub) => ({
|
||||
(
|
||||
fileName: string,
|
||||
fileExtension: SupportedFileExtension,
|
||||
hubType: Hub | undefined,
|
||||
) => ({
|
||||
type: 'explorer.newFileWizard.action.didAccept',
|
||||
fileName,
|
||||
fileExtension,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
{
|
||||
"title": "Create a new file",
|
||||
"smartHub": {
|
||||
"label": "Smart hub"
|
||||
"template": {
|
||||
"label": "Template"
|
||||
},
|
||||
"emptyFile": {
|
||||
"label": "Create an empty file"
|
||||
},
|
||||
"action": {
|
||||
"create": "Create"
|
||||
|
||||
Reference in New Issue
Block a user