mirror of
https://github.com/drawdb-io/drawdb.git
synced 2025-05-24 10:29:11 +00:00
Refactor AreasContextProvider: Add context export, custom hook, PropTypes validation, and error handling
- Added `AreasContext` export and created `useAreasContext` custom hook for safer and easier context access. - Integrated `PropTypes` to validate `children` prop in `AreasContextProvider` component. - Refactored `addArea` function by breaking it into `addExistingArea` and `addNewArea` for improved readability and maintainability. - Added error handling in `deleteArea` function to prevent operations with invalid IDs. - Extracted logic to clear selected element into a separate function for better separation of concerns. - Ensured proper default export for `AreasContextProvider` to facilitate correct imports. These changes improve code robustness, readability, and type safety in the JavaScript environment.
This commit is contained in:
parent
2f26d12f6a
commit
d938f72e1d
51
package-lock.json
generated
51
package-lock.json
generated
@ -43,7 +43,7 @@
|
||||
"@types/react-dom": "^18.2.17",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"eslint": "^8.55.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
@ -1111,22 +1111,25 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "8.56.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
|
||||
"integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
|
||||
"version": "8.57.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
|
||||
"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.13",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
||||
"integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
||||
"deprecated": "Use @eslint/config-array instead",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^2.0.1",
|
||||
"debug": "^4.1.1",
|
||||
"@humanwhocodes/object-schema": "^2.0.2",
|
||||
"debug": "^4.3.1",
|
||||
"minimatch": "^3.0.5"
|
||||
},
|
||||
"engines": {
|
||||
@ -1147,10 +1150,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/object-schema": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
|
||||
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
|
||||
"dev": true
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
|
||||
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||
"deprecated": "Use @eslint/object-schema instead",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.3",
|
||||
@ -2317,9 +2322,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001570",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz",
|
||||
"integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==",
|
||||
"version": "1.0.30001651",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
|
||||
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -2334,7 +2339,8 @@
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
]
|
||||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/canvg": {
|
||||
"version": "3.0.10",
|
||||
@ -2873,16 +2879,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.56.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
|
||||
"integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
|
||||
"version": "8.57.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
|
||||
"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.6.1",
|
||||
"@eslint/eslintrc": "^2.1.4",
|
||||
"@eslint/js": "8.56.0",
|
||||
"@humanwhocodes/config-array": "^0.11.13",
|
||||
"@eslint/js": "8.57.0",
|
||||
"@humanwhocodes/config-array": "^0.11.14",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
"@ungap/structured-clone": "^1.2.0",
|
||||
|
@ -45,7 +45,7 @@
|
||||
"@types/react-dom": "^18.2.17",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"eslint": "^8.55.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
|
@ -1,12 +1,23 @@
|
||||
import { createContext, useState } from "react";
|
||||
import { Action, ObjectType, defaultBlue } from "../data/constants";
|
||||
import { useUndoRedo, useTransform, useSelect } from "../hooks";
|
||||
import { Toast } from "@douyinfe/semi-ui";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import React, { createContext, useState, ReactNode, useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Action, ObjectType, defaultBlue } from '../data/constants';
|
||||
import { useUndoRedo, useTransform, useSelect } from '../hooks';
|
||||
import { Toast } from '@douyinfe/semi-ui';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const AreasContext = createContext(null);
|
||||
// Define context
|
||||
export const AreasContext = createContext(null); // Ensure export is here
|
||||
|
||||
export default function AreasContextProvider({ children }) {
|
||||
export const useAreasContext = () => {
|
||||
const context = useContext(AreasContext);
|
||||
if (!context) {
|
||||
throw new Error('useAreasContext must be used within an AreasContextProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
// AreasContextProvider component
|
||||
const AreasContextProvider = ({ children }) => {
|
||||
const { t } = useTranslation();
|
||||
const [areas, setAreas] = useState([]);
|
||||
const { transform } = useTransform();
|
||||
@ -15,15 +26,27 @@ export default function AreasContextProvider({ children }) {
|
||||
|
||||
const addArea = (data, addToHistory = true) => {
|
||||
if (data) {
|
||||
setAreas((prev) => {
|
||||
const temp = prev.slice();
|
||||
temp.splice(data.id, 0, data);
|
||||
return temp.map((t, i) => ({ ...t, id: i }));
|
||||
});
|
||||
addExistingArea(data);
|
||||
} else {
|
||||
addNewArea();
|
||||
}
|
||||
if (addToHistory) {
|
||||
addActionToHistory(Action.ADD, ObjectType.AREA, t("add_area"));
|
||||
}
|
||||
};
|
||||
|
||||
const addExistingArea = (data) => {
|
||||
setAreas(prev => {
|
||||
const updatedAreas = [...prev];
|
||||
updatedAreas.splice(data.id, 0, data);
|
||||
return updatedAreas.map((area, i) => ({ ...area, id: i }));
|
||||
});
|
||||
};
|
||||
|
||||
const addNewArea = () => {
|
||||
const width = 200;
|
||||
const height = 200;
|
||||
setAreas((prev) => [
|
||||
setAreas(prev => [
|
||||
...prev,
|
||||
{
|
||||
id: prev.length,
|
||||
@ -35,66 +58,52 @@ export default function AreasContextProvider({ children }) {
|
||||
color: defaultBlue,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (addToHistory) {
|
||||
setUndoStack((prev) => [
|
||||
...prev,
|
||||
{
|
||||
action: Action.ADD,
|
||||
element: ObjectType.AREA,
|
||||
message: t("add_area"),
|
||||
},
|
||||
]);
|
||||
setRedoStack([]);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteArea = (id, addToHistory = true) => {
|
||||
if (id < 0 || id >= areas.length) return; // Handle invalid ID
|
||||
if (addToHistory) {
|
||||
Toast.success(t("area_deleted"));
|
||||
setUndoStack((prev) => [
|
||||
...prev,
|
||||
{
|
||||
action: Action.DELETE,
|
||||
element: ObjectType.AREA,
|
||||
data: areas[id],
|
||||
message: t("delete_area", areas[id].name),
|
||||
},
|
||||
]);
|
||||
setRedoStack([]);
|
||||
addActionToHistory(Action.DELETE, ObjectType.AREA, t("delete_area", areas[id].name), areas[id]);
|
||||
}
|
||||
setAreas((prev) =>
|
||||
prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i })),
|
||||
);
|
||||
setAreas(prev => {
|
||||
const filteredAreas = prev.filter(e => e.id !== id);
|
||||
return filteredAreas.map((e, i) => ({ ...e, id: i }));
|
||||
});
|
||||
if (id === selectedElement.id) {
|
||||
setSelectedElement((prev) => ({
|
||||
...prev,
|
||||
clearSelectedElement();
|
||||
}
|
||||
};
|
||||
|
||||
const clearSelectedElement = () => {
|
||||
setSelectedElement({
|
||||
element: ObjectType.NONE,
|
||||
id: -1,
|
||||
open: false,
|
||||
}));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const updateArea = (id, values) => {
|
||||
setAreas((prev) =>
|
||||
prev.map((t) => {
|
||||
if (t.id === id) {
|
||||
return {
|
||||
...t,
|
||||
...values,
|
||||
setAreas(prev => prev.map(area => area.id === id ? { ...area, ...values } : area));
|
||||
};
|
||||
}
|
||||
return t;
|
||||
}),
|
||||
);
|
||||
|
||||
const addActionToHistory = (action, element, message, data) => {
|
||||
setUndoStack(prev => [
|
||||
...prev,
|
||||
{ action, element, message, data },
|
||||
]);
|
||||
setRedoStack([]);
|
||||
};
|
||||
|
||||
return (
|
||||
<AreasContext.Provider
|
||||
value={{ areas, setAreas, updateArea, addArea, deleteArea }}
|
||||
>
|
||||
<AreasContext.Provider value={{ areas, setAreas, updateArea, addArea, deleteArea }}>
|
||||
{children}
|
||||
</AreasContext.Provider>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
AreasContextProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default AreasContextProvider;
|
||||
|
Loading…
Reference in New Issue
Block a user