update: move all functionalities from dialog to drawer

This commit is contained in:
Daniel Gonzalez Albo
2025-11-07 02:06:53 +01:00
committed by Nicolás Hatcher Andrés
parent d8b3ba0dae
commit 4217c1455b
4 changed files with 458 additions and 8 deletions

View File

@@ -1,20 +1,154 @@
import type { DefinedName, WorksheetProperties } from "@ironcalc/wasm";
import { Button, Tooltip, styled } from "@mui/material";
import { t } from "i18next";
import { BookOpen, Plus } from "lucide-react";
import type React from "react";
import { BookOpen, ChevronRight, Plus } from "lucide-react";
import { useState } from "react";
import { theme } from "../../../theme";
import EditNamedRange from "./EditNamedRange";
interface NamedRangesProps {
title?: string;
definedNameList?: DefinedName[];
worksheets?: WorksheetProperties[];
updateDefinedName?: (
name: string,
scope: number | undefined,
newName: string,
newScope: number | undefined,
newFormula: string,
) => void;
newDefinedName?: (
name: string,
scope: number | undefined,
formula: string,
) => void;
selectedArea?: () => string;
}
const NamedRanges: React.FC<NamedRangesProps> = ({
title = "Named Ranges",
definedNameList = [],
worksheets = [],
updateDefinedName,
newDefinedName,
selectedArea,
}) => {
const [editingDefinedName, setEditingDefinedName] =
useState<DefinedName | null>(null);
const [isCreatingNew, setIsCreatingNew] = useState(false);
const handleListItemClick = (definedName: DefinedName) => {
setEditingDefinedName(definedName);
setIsCreatingNew(false);
};
const handleNewClick = () => {
setIsCreatingNew(true);
setEditingDefinedName(null);
};
const handleCancel = () => {
setEditingDefinedName(null);
setIsCreatingNew(false);
};
const handleSave = (
name: string,
scope: string,
formula: string,
): string | undefined => {
if (isCreatingNew) {
if (!newDefinedName) return undefined;
const scope_index = worksheets.findIndex((s) => s.name === scope);
const newScope = scope_index >= 0 ? scope_index : undefined;
try {
newDefinedName(name, newScope, formula);
setIsCreatingNew(false);
return undefined;
} catch (e) {
return `${e}`;
}
} else {
if (!editingDefinedName || !updateDefinedName) return undefined;
const scope_index = worksheets.findIndex((s) => s.name === scope);
const newScope = scope_index >= 0 ? scope_index : undefined;
try {
updateDefinedName(
editingDefinedName.name,
editingDefinedName.scope,
name,
newScope,
formula,
);
setEditingDefinedName(null);
return undefined;
} catch (e) {
return `${e}`;
}
}
};
// Show edit view if a named range is being edited or created
if (editingDefinedName || isCreatingNew) {
let name = "";
let scopeName = "[global]";
let formula = "";
if (editingDefinedName) {
name = editingDefinedName.name;
scopeName =
editingDefinedName.scope !== undefined
? worksheets[editingDefinedName.scope]?.name || "[unknown]"
: "[global]";
formula = editingDefinedName.formula;
} else if (isCreatingNew && selectedArea) {
formula = selectedArea();
}
return (
<Container>
<Content>
<EditNamedRange
worksheets={worksheets}
name={name}
scope={scopeName}
formula={formula}
onSave={handleSave}
onCancel={handleCancel}
/>
</Content>
</Container>
);
}
// Show list view
return (
<Container>
<Content>
<h3>{title}</h3>
{definedNameList.length > 0 && (
<ListContainer>
{definedNameList.map((definedName) => {
const scopeName =
definedName.scope !== undefined
? worksheets[definedName.scope]?.name || "[unknown]"
: "[global]";
return (
<ListItem
key={`${definedName.name}-${definedName.scope}`}
onClick={() => handleListItemClick(definedName)}
tabIndex={0}
>
<ListItemText>
<ScopeText>{scopeName}</ScopeText>
<ChevronRightStyled />
<NameText>{definedName.name}</NameText>
</ListItemText>
</ListItem>
);
})}
</ListContainer>
)}
</Content>
<Footer>
<Tooltip
@@ -37,6 +171,7 @@ const NamedRanges: React.FC<NamedRangesProps> = ({
variant="contained"
disableElevation
startIcon={<Plus size={16} />}
onClick={handleNewClick}
>
{t("name_manager_dialog.new")}
</NewButton>
@@ -55,12 +190,54 @@ const Content = styled("div")({
flex: 1,
color: theme.palette.grey[700],
lineHeight: "1.5",
overflow: "auto",
});
"& p": {
margin: "0 0 12px 0",
const ListContainer = styled("div")({
display: "flex",
flexDirection: "column",
});
const ListItem = styled("div")({
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "8px 12px",
minHeight: "40px",
cursor: "pointer",
boxSizing: "border-box",
borderBottom: `1px solid ${theme.palette.grey[200]}`,
"&:hover": {
backgroundColor: theme.palette.grey[50],
},
});
const ListItemText = styled("div")({
fontSize: "12px",
color: theme.palette.common.black,
fontFamily: theme.typography.fontFamily,
flex: 1,
display: "flex",
alignItems: "center",
gap: "4px",
});
const ScopeText = styled("span")({
fontSize: "12px",
color: theme.palette.common.black,
});
const ChevronRightStyled = styled(ChevronRight)({
width: "12px",
height: "12px",
color: theme.palette.grey[500],
});
const NameText = styled("span")({
fontSize: "12px",
color: theme.palette.common.black,
});
const Footer = styled("div")`
padding: 8px;
display: flex;
@@ -93,6 +270,7 @@ const HelpLink = styled("a")`
const NewButton = styled(Button)`
text-transform: none;
min-width: fit-content;
font-size: 12px;
`;
export default NamedRanges;