Merge pull request #255 from XRPLF/feat/tab-renames
Implement file renaming.
This commit is contained in:
@@ -15,37 +15,11 @@ import {
|
|||||||
ContextMenuTriggerItem,
|
ContextMenuTriggerItem,
|
||||||
} from "./primitive";
|
} from "./primitive";
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
label: "Show bookmarks",
|
|
||||||
type: "checkbox",
|
|
||||||
checked: true,
|
|
||||||
indicator: "*",
|
|
||||||
onCheckedChange: () => {},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "radio",
|
|
||||||
label: "People",
|
|
||||||
value: "pedro",
|
|
||||||
onValueChange: () => {},
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: "pedro",
|
|
||||||
label: "Pedro Duarte",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "colm",
|
|
||||||
label: "Colm Tuite",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export type TextOption = {
|
export type TextOption = {
|
||||||
type: "text";
|
type: "text";
|
||||||
label: ReactNode;
|
label: ReactNode;
|
||||||
onClick?: () => any;
|
onSelect?: () => any;
|
||||||
children?: Option[];
|
children?: ContentMenuOption[];
|
||||||
};
|
};
|
||||||
export type SeparatorOption = { type: "separator" };
|
export type SeparatorOption = { type: "separator" };
|
||||||
export type CheckboxOption = {
|
export type CheckboxOption = {
|
||||||
@@ -64,11 +38,16 @@ export type RadioOption<T extends string = string> = {
|
|||||||
|
|
||||||
type WithCommons = { key: string; disabled?: boolean };
|
type WithCommons = { key: string; disabled?: boolean };
|
||||||
|
|
||||||
type Option = (TextOption | SeparatorOption | CheckboxOption | RadioOption) &
|
export type ContentMenuOption = (
|
||||||
|
| TextOption
|
||||||
|
| SeparatorOption
|
||||||
|
| CheckboxOption
|
||||||
|
| RadioOption
|
||||||
|
) &
|
||||||
WithCommons;
|
WithCommons;
|
||||||
|
|
||||||
interface IContextMenu {
|
export interface IContextMenu {
|
||||||
options?: Option[];
|
options?: ContentMenuOption[];
|
||||||
isNested?: boolean;
|
isNested?: boolean;
|
||||||
}
|
}
|
||||||
export const ContextMenu: FC<IContextMenu> = ({
|
export const ContextMenu: FC<IContextMenu> = ({
|
||||||
@@ -83,11 +62,11 @@ export const ContextMenu: FC<IContextMenu> = ({
|
|||||||
) : (
|
) : (
|
||||||
<ContextMenuTrigger>{children}</ContextMenuTrigger>
|
<ContextMenuTrigger>{children}</ContextMenuTrigger>
|
||||||
)}
|
)}
|
||||||
{options && (
|
{options && !!options.length && (
|
||||||
<ContextMenuContent sideOffset={isNested ? 2 : 5}>
|
<ContextMenuContent sideOffset={isNested ? 2 : 5}>
|
||||||
{options.map(({ key, ...option }) => {
|
{options.map(({ key, ...option }) => {
|
||||||
if (option.type === "text") {
|
if (option.type === "text") {
|
||||||
const { children, label } = option;
|
const { children, label, onSelect } = option;
|
||||||
if (children)
|
if (children)
|
||||||
return (
|
return (
|
||||||
<ContextMenu isNested key={key} options={children}>
|
<ContextMenu isNested key={key} options={children}>
|
||||||
@@ -97,7 +76,11 @@ export const ContextMenu: FC<IContextMenu> = ({
|
|||||||
</Flex>
|
</Flex>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
);
|
);
|
||||||
return <ContextMenuItem key={key}>{label}</ContextMenuItem>;
|
return (
|
||||||
|
<ContextMenuItem key={key} onSelect={onSelect}>
|
||||||
|
{label}
|
||||||
|
</ContextMenuItem>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (option.type === "checkbox") {
|
if (option.type === "checkbox") {
|
||||||
const { label, checked, onCheckedChange } = option;
|
const { label, checked, onCheckedChange } = option;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const contentShow = keyframes({
|
|||||||
"100%": { opacity: 1 },
|
"100%": { opacity: 1 },
|
||||||
});
|
});
|
||||||
const StyledOverlay = styled(DialogPrimitive.Overlay, {
|
const StyledOverlay = styled(DialogPrimitive.Overlay, {
|
||||||
zIndex: 9999,
|
zIndex: 10000,
|
||||||
backgroundColor: blackA.blackA9,
|
backgroundColor: blackA.blackA9,
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
inset: 0,
|
inset: 0,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import docs from "../xrpl-hooks-docs/docs";
|
|||||||
import Monaco from "./Monaco";
|
import Monaco from "./Monaco";
|
||||||
import { saveAllFiles } from "../state/actions/saveFile";
|
import { saveAllFiles } from "../state/actions/saveFile";
|
||||||
import { Tab, Tabs } from "./Tabs";
|
import { Tab, Tabs } from "./Tabs";
|
||||||
|
import { renameFile } from "../state/actions/createNewFile";
|
||||||
|
|
||||||
const validateWritability = (editor: monaco.editor.IStandaloneCodeEditor) => {
|
const validateWritability = (editor: monaco.editor.IStandaloneCodeEditor) => {
|
||||||
const currPath = editor.getModel()?.uri.path;
|
const currPath = editor.getModel()?.uri.path;
|
||||||
@@ -129,6 +130,7 @@ const HooksEditor = () => {
|
|||||||
extensionRequired
|
extensionRequired
|
||||||
onCreateNewTab={createNewFile}
|
onCreateNewTab={createNewFile}
|
||||||
onCloseTab={idx => state.files.splice(idx, 1)}
|
onCloseTab={idx => state.files.splice(idx, 1)}
|
||||||
|
onRenameTab={(idx, nwName, oldName = "") => renameFile(oldName, nwName)}
|
||||||
headerExtraValidation={{
|
headerExtraValidation={{
|
||||||
regex: /^[A-Za-z0-9_-]+[.][A-Za-z0-9]{1,4}$/g,
|
regex: /^[A-Za-z0-9_-]+[.][A-Za-z0-9]{1,4}$/g,
|
||||||
error:
|
error:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import React, {
|
|||||||
useCallback,
|
useCallback,
|
||||||
} from "react";
|
} from "react";
|
||||||
import type { ReactNode, ReactElement } from "react";
|
import type { ReactNode, ReactElement } from "react";
|
||||||
import { Box, Button, Flex, Input, Label, Stack, Text } from ".";
|
import { Box, Button, Flex, Input, Label, Pre, Stack, Text } from ".";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
import { Plus, X } from "phosphor-react";
|
import { Plus, X } from "phosphor-react";
|
||||||
import { styled } from "../stitches.config";
|
import { styled } from "../stitches.config";
|
||||||
import { capitalize } from "../utils/helpers";
|
import { capitalize } from "../utils/helpers";
|
||||||
import ContextMenu from "./ContextMenu";
|
import ContextMenu, { ContentMenuOption } from "./ContextMenu";
|
||||||
|
|
||||||
const ErrorText = styled(Text, {
|
const ErrorText = styled(Text, {
|
||||||
color: "$error",
|
color: "$error",
|
||||||
@@ -26,6 +26,8 @@ const ErrorText = styled(Text, {
|
|||||||
display: "block",
|
display: "block",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type Nullable<T> = T | null | undefined | false;
|
||||||
|
|
||||||
interface TabProps {
|
interface TabProps {
|
||||||
header: string;
|
header: string;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
@@ -47,6 +49,7 @@ interface Props {
|
|||||||
error: string;
|
error: string;
|
||||||
};
|
};
|
||||||
onCreateNewTab?: (name: string) => any;
|
onCreateNewTab?: (name: string) => any;
|
||||||
|
onRenameTab?: (index: number, nwName: string, oldName?: string) => any;
|
||||||
onCloseTab?: (index: number, header?: string) => any;
|
onCloseTab?: (index: number, header?: string) => any;
|
||||||
onChangeActive?: (index: number, header?: string) => any;
|
onChangeActive?: (index: number, header?: string) => any;
|
||||||
}
|
}
|
||||||
@@ -63,6 +66,7 @@ export const Tabs = ({
|
|||||||
onCreateNewTab,
|
onCreateNewTab,
|
||||||
onCloseTab,
|
onCloseTab,
|
||||||
onChangeActive,
|
onChangeActive,
|
||||||
|
onRenameTab,
|
||||||
headerExtraValidation,
|
headerExtraValidation,
|
||||||
extensionRequired,
|
extensionRequired,
|
||||||
defaultExtension = "",
|
defaultExtension = "",
|
||||||
@@ -72,8 +76,9 @@ export const Tabs = ({
|
|||||||
const tabs: TabProps[] = children.map(elem => elem.props);
|
const tabs: TabProps[] = children.map(elem => elem.props);
|
||||||
|
|
||||||
const [isNewtabDialogOpen, setIsNewtabDialogOpen] = useState(false);
|
const [isNewtabDialogOpen, setIsNewtabDialogOpen] = useState(false);
|
||||||
|
const [renamingTab, setRenamingTab] = useState<number | null>(null);
|
||||||
const [tabname, setTabname] = useState("");
|
const [tabname, setTabname] = useState("");
|
||||||
const [newtabError, setNewtabError] = useState<string | null>(null);
|
const [tabnameError, setTabnameError] = useState<string | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeIndex) setActive(activeIndex);
|
if (activeIndex) setActive(activeIndex);
|
||||||
@@ -89,21 +94,24 @@ export const Tabs = ({
|
|||||||
|
|
||||||
// when filename changes, reset error
|
// when filename changes, reset error
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNewtabError(null);
|
setTabnameError(null);
|
||||||
}, [tabname, setNewtabError]);
|
}, [tabname, setTabnameError]);
|
||||||
|
|
||||||
const validateTabname = useCallback(
|
const validateTabname = useCallback(
|
||||||
(tabname: string): { error: string | null } => {
|
(tabname: string): { error?: string, result?: string } => {
|
||||||
if (!tabname) {
|
if (!tabname) {
|
||||||
return { error: `Please enter ${label.toLocaleLowerCase()} name.` };
|
return { error: `Please enter ${label.toLocaleLowerCase()} name.` };
|
||||||
}
|
}
|
||||||
|
let ext =
|
||||||
|
(tabname.includes(".") && tabname.split(".").pop()) || "";
|
||||||
|
|
||||||
|
if (!ext && defaultExtension) {
|
||||||
|
ext = defaultExtension
|
||||||
|
tabname = `${tabname}.${defaultExtension}`
|
||||||
|
}
|
||||||
if (tabs.find(tab => tab.header === tabname)) {
|
if (tabs.find(tab => tab.header === tabname)) {
|
||||||
return { error: `${capitalize(label)} name already exists.` };
|
return { error: `${capitalize(label)} name already exists.` };
|
||||||
}
|
}
|
||||||
const ext =
|
|
||||||
(tabname.includes(".") && tabname.split(".").pop()) ||
|
|
||||||
defaultExtension ||
|
|
||||||
"";
|
|
||||||
if (extensionRequired && !ext) {
|
if (extensionRequired && !ext) {
|
||||||
return { error: "File extension is required!" };
|
return { error: "File extension is required!" };
|
||||||
}
|
}
|
||||||
@@ -116,7 +124,7 @@ export const Tabs = ({
|
|||||||
) {
|
) {
|
||||||
return { error: headerExtraValidation.error };
|
return { error: headerExtraValidation.error };
|
||||||
}
|
}
|
||||||
return { error: null };
|
return { result: tabname };
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
allowedExtensions,
|
allowedExtensions,
|
||||||
@@ -136,16 +144,33 @@ export const Tabs = ({
|
|||||||
[onChangeActive]
|
[onChangeActive]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleCreateTab = useCallback(() => {
|
const handleRenameTab = useCallback(() => {
|
||||||
const chk = validateTabname(tabname);
|
if (renamingTab === null) return;
|
||||||
if (chk.error) {
|
|
||||||
setNewtabError(`Error: ${chk.error}`);
|
const res = validateTabname(tabname);
|
||||||
|
if (res.error) {
|
||||||
|
setTabnameError(`Error: ${res.error}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let _tabname = tabname;
|
|
||||||
if (defaultExtension && !_tabname.endsWith(defaultExtension)) {
|
const { result: _tabname = tabname } = res
|
||||||
_tabname = `${_tabname}.${defaultExtension}`;
|
|
||||||
|
setRenamingTab(null);
|
||||||
|
setTabname("");
|
||||||
|
|
||||||
|
const oldName = tabs[renamingTab]?.header;
|
||||||
|
onRenameTab?.(renamingTab, _tabname, oldName);
|
||||||
|
|
||||||
|
handleActiveChange(renamingTab);
|
||||||
|
}, [handleActiveChange, onRenameTab, renamingTab, tabname, tabs, validateTabname]);
|
||||||
|
|
||||||
|
const handleCreateTab = useCallback(() => {
|
||||||
|
const res = validateTabname(tabname);
|
||||||
|
if (res.error) {
|
||||||
|
setTabnameError(`Error: ${res.error}`);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const { result: _tabname = tabname } = res
|
||||||
|
|
||||||
setIsNewtabDialogOpen(false);
|
setIsNewtabDialogOpen(false);
|
||||||
setTabname("");
|
setTabname("");
|
||||||
@@ -153,14 +178,7 @@ export const Tabs = ({
|
|||||||
onCreateNewTab?.(_tabname);
|
onCreateNewTab?.(_tabname);
|
||||||
|
|
||||||
handleActiveChange(tabs.length, _tabname);
|
handleActiveChange(tabs.length, _tabname);
|
||||||
}, [
|
}, [validateTabname, tabname, onCreateNewTab, handleActiveChange, tabs.length]);
|
||||||
tabname,
|
|
||||||
defaultExtension,
|
|
||||||
validateTabname,
|
|
||||||
onCreateNewTab,
|
|
||||||
handleActiveChange,
|
|
||||||
tabs.length,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const handleCloseTab = useCallback(
|
const handleCloseTab = useCallback(
|
||||||
(idx: number) => {
|
(idx: number) => {
|
||||||
@@ -175,6 +193,21 @@ export const Tabs = ({
|
|||||||
[active, handleActiveChange, onCloseTab, tabs]
|
[active, handleActiveChange, onCloseTab, tabs]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const closeOption = (idx: number): Nullable<ContentMenuOption> =>
|
||||||
|
onCloseTab && {
|
||||||
|
type: "text",
|
||||||
|
label: "Close",
|
||||||
|
key: "close",
|
||||||
|
onSelect: () => handleCloseTab(idx),
|
||||||
|
};
|
||||||
|
const renameOption = (idx: number): Nullable<ContentMenuOption> =>
|
||||||
|
onRenameTab && {
|
||||||
|
type: "text",
|
||||||
|
label: "Rename",
|
||||||
|
key: "rename",
|
||||||
|
onSelect: () => setRenamingTab(idx),
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!headless && (
|
{!headless && (
|
||||||
@@ -189,7 +222,14 @@ export const Tabs = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tabs.map((tab, idx) => (
|
{tabs.map((tab, idx) => (
|
||||||
<ContextMenu key={tab.header}>
|
<ContextMenu
|
||||||
|
key={tab.header}
|
||||||
|
options={
|
||||||
|
[closeOption(idx), renameOption(idx)].filter(
|
||||||
|
Boolean
|
||||||
|
) as ContentMenuOption[]
|
||||||
|
}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
role="tab"
|
role="tab"
|
||||||
tabIndex={idx}
|
tabIndex={idx}
|
||||||
@@ -261,7 +301,7 @@ export const Tabs = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ErrorText>{newtabError}</ErrorText>
|
<ErrorText>{tabnameError}</ErrorText>
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
|
|
||||||
<Flex
|
<Flex
|
||||||
@@ -286,6 +326,51 @@ export const Tabs = ({
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)}
|
)}
|
||||||
|
{onRenameTab && (
|
||||||
|
<Dialog
|
||||||
|
open={renamingTab !== null}
|
||||||
|
onOpenChange={() => setRenamingTab(null)}
|
||||||
|
>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogTitle>
|
||||||
|
Rename <Pre>{tabs[renamingTab || 0]?.header}</Pre>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
<Label>Enter new name</Label>
|
||||||
|
<Input
|
||||||
|
value={tabname}
|
||||||
|
onChange={e => setTabname(e.target.value)}
|
||||||
|
onKeyPress={e => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
handleRenameTab();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ErrorText>{tabnameError}</ErrorText>
|
||||||
|
</DialogDescription>
|
||||||
|
|
||||||
|
<Flex
|
||||||
|
css={{
|
||||||
|
marginTop: 25,
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
gap: "$3",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Button outline>Cancel</Button>
|
||||||
|
</DialogClose>
|
||||||
|
<Button variant="primary" onClick={handleRenameTab}>
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Box css={{ position: "absolute", top: "$3", right: "$3" }}>
|
||||||
|
<X size="20px" />
|
||||||
|
</Box>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
{keepAllAlive
|
{keepAllAlive
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import state from "../../state";
|
|||||||
import {
|
import {
|
||||||
defaultTransactionType,
|
defaultTransactionType,
|
||||||
getTxFields,
|
getTxFields,
|
||||||
modifyTransaction,
|
modifyTxState,
|
||||||
prepareState,
|
prepareState,
|
||||||
prepareTransaction,
|
prepareTransaction,
|
||||||
SelectOption,
|
SelectOption,
|
||||||
@@ -42,7 +42,7 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
|
|
||||||
const setState = useCallback(
|
const setState = useCallback(
|
||||||
(pTx?: Partial<TransactionState>) => {
|
(pTx?: Partial<TransactionState>) => {
|
||||||
return modifyTransaction(header, pTx);
|
return modifyTxState(header, pTx);
|
||||||
},
|
},
|
||||||
[header]
|
[header]
|
||||||
);
|
);
|
||||||
@@ -164,7 +164,7 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
}
|
}
|
||||||
nwState.txFields = fields;
|
nwState.txFields = fields;
|
||||||
|
|
||||||
const state = modifyTransaction(header, nwState, { replaceState: true });
|
const state = modifyTxState(header, nwState, { replaceState: true });
|
||||||
const editorValue = getJsonString(state);
|
const editorValue = getJsonString(state);
|
||||||
return setState({ editorValue });
|
return setState({ editorValue });
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import Split from "react-split";
|
|||||||
import { useSnapshot } from "valtio";
|
import { useSnapshot } from "valtio";
|
||||||
import { Box, Container, Flex, Tab, Tabs } from "../../components";
|
import { Box, Container, Flex, Tab, Tabs } from "../../components";
|
||||||
import Transaction from "../../components/Transaction";
|
import Transaction from "../../components/Transaction";
|
||||||
import state from "../../state";
|
import state, { renameTxState } from "../../state";
|
||||||
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
|
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
|
||||||
import { transactionsState, modifyTransaction } from "../../state";
|
import { transactionsState, modifyTxState } from "../../state";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FileJs } from "phosphor-react";
|
import { FileJs } from "phosphor-react";
|
||||||
import RunScript from '../../components/RunScript';
|
import RunScript from "../../components/RunScript";
|
||||||
|
|
||||||
const DebugStream = dynamic(() => import("../../components/DebugStream"), {
|
const DebugStream = dynamic(() => import("../../components/DebugStream"), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
@@ -96,9 +96,12 @@ const Test = () => {
|
|||||||
keepAllAlive
|
keepAllAlive
|
||||||
defaultExtension="json"
|
defaultExtension="json"
|
||||||
allowedExtensions={["json"]}
|
allowedExtensions={["json"]}
|
||||||
onCreateNewTab={header => modifyTransaction(header, {})}
|
onCreateNewTab={header => modifyTxState(header, {})}
|
||||||
|
onRenameTab={(idx, nwName, oldName = "") =>
|
||||||
|
renameTxState(oldName, nwName)
|
||||||
|
}
|
||||||
onCloseTab={(idx, header) =>
|
onCloseTab={(idx, header) =>
|
||||||
header && modifyTransaction(header, undefined)
|
header && modifyTxState(header, undefined)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{transactions.map(({ header, state }) => (
|
{transactions.map(({ header, state }) => (
|
||||||
|
|||||||
@@ -14,4 +14,11 @@ export const createNewFile = (name: string) => {
|
|||||||
const emptyFile: IFile = { name, language: languageMapping[fileExt as 'ts' | 'js' | 'md' | 'c' | 'h' | 'other'], content: "" };
|
const emptyFile: IFile = { name, language: languageMapping[fileExt as 'ts' | 'js' | 'md' | 'c' | 'h' | 'other'], content: "" };
|
||||||
state.files.push(emptyFile);
|
state.files.push(emptyFile);
|
||||||
state.active = state.files.length - 1;
|
state.active = state.files.length - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const renameFile = (oldName: string, nwName: string) => {
|
||||||
|
const file = state.files.find(file => file.name === oldName)
|
||||||
|
if (!file) throw Error(`No file exists with name ${oldName}`)
|
||||||
|
|
||||||
|
file.name = nwName
|
||||||
};
|
};
|
||||||
@@ -48,13 +48,21 @@ export const transactionsState = proxy({
|
|||||||
activeHeader: "test1.json"
|
activeHeader: "test1.json"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const renameTxState = (oldName: string, nwName: string) => {
|
||||||
|
const tx = transactionsState.transactions.find(tx => tx.header === oldName);
|
||||||
|
|
||||||
|
if (!tx) throw Error(`No transaction state exists with given header name ${oldName}`);
|
||||||
|
|
||||||
|
tx.header = nwName
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple transaction state changer
|
* Simple transaction state changer
|
||||||
* @param header Unique key and tab name for the transaction tab
|
* @param header Unique key and tab name for the transaction tab
|
||||||
* @param partialTx partial transaction state, `undefined` deletes the transaction
|
* @param partialTx partial transaction state, `undefined` deletes the transaction
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export const modifyTransaction = (
|
export const modifyTxState = (
|
||||||
header: string,
|
header: string,
|
||||||
partialTx?: Partial<TransactionState>,
|
partialTx?: Partial<TransactionState>,
|
||||||
opts: { replaceState?: boolean } = {}
|
opts: { replaceState?: boolean } = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user