Skip to content

Commit

Permalink
Merge pull request #253 from NucleoidAI/250-expendable-resources
Browse files Browse the repository at this point in the history
Resource Node Selection and Arrows in APITree
  • Loading branch information
canmingir authored May 11, 2024
2 parents a5192f7 + 563a7f1 commit ea53625
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 35 deletions.
21 changes: 15 additions & 6 deletions src/components/DeleteResourceDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,21 @@ const DeleteResourceDialog = forwardRef(({ setOpen, deleteResource }, ref) => {
>
<DialogTitle id="responsive-dialog-title">Delete resource</DialogTitle>
<DialogContent>
The selected resource and all methods and resources under it will be
deleted. Resources to be deleted :<br />
<br />
{resource.deleteList.map((item, index) => {
return <Typography key={index}>{item}</Typography>;
})}
<Typography>
{`The selected resource "${resource?.deleteAdress}" will be deleted.`}
</Typography>
{resource?.deleteList.length > 0 && (
<>
<Typography sx={{ mt: 2 }}>
The following child resources will also be deleted:
</Typography>
{resource?.deleteList.map((item, index) => (
<Typography key={index} sx={{ ml: 2 }}>
- {item}
</Typography>
))}
</>
)}
</DialogContent>
<DialogActions>
<Button autoFocus onClick={handleClose}>
Expand Down
30 changes: 20 additions & 10 deletions src/context/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,27 @@ function contextReducer(context, { type, payload }) {
break;

case "DELETE_RESOURCE": {
const newObj = {};
// TODO functional programming
Object.keys(context.specification.api)
.filter((item) => !item.includes(context.pages.api.selected.path))
.forEach(
(objName) => (newObj[objName] = context.specification.api[objName])
);
const { path } = payload;

specification.api = specification.api.filter(
(api) => !api.path.startsWith(path)
);

if (pages.api.selected.path.startsWith(path)) {
if (specification.api.length > 0) {
pages.api.selected.path = specification.api[0].path;
pages.api.selected.method = specification.api[0].method;
} else {
pages.api.selected.path = "/";
pages.api.selected.method = "get";
}

publish("SELECTED_API_CHANGED", {
path: pages.api.selected.path,
method: pages.api.selected.method,
});
}

context.specification.api = newObj;
context.pages.api.selected.path = "/";
context.pages.api.selected.method = "get";
break;
}

Expand Down
12 changes: 5 additions & 7 deletions src/icons/Arrow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
import React from "react";

const style = {
fill: "#212121",
};
// fill: "#212121", old fill color

function Arrow({ up, down, right, left }) {
return up ? (
<KeyboardArrowUpIcon style={style} />
<KeyboardArrowUpIcon />
) : down ? (
<KeyboardArrowDownIcon style={style} />
<KeyboardArrowDownIcon />
) : right ? (
<KeyboardArrowRightIcon style={style} />
<KeyboardArrowRightIcon />
) : left ? (
<KeyboardArrowLeftIcon style={style} />
<KeyboardArrowLeftIcon />
) : null;
}

Expand Down
2 changes: 1 addition & 1 deletion src/templates/apiActionTemplates.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const apiActionTemplates = {
return { id: id, name: name };
}`,

DELETE: `function action(req) {
DEL: `function action(req) {
const { id } = req.params;
return { message: \`Resource with ID \${id} deleted successfully\` };
}`,
Expand Down
2 changes: 1 addition & 1 deletion src/widgets/APIDialog/APIDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function APIDialog() {
const contextApis = context.specification.api;

let selectedApi = null;
let allowedMethods = ["GET", "POST", "PUT", "DELETE", "PATCH"];
let allowedMethods = ["GET", "POST", "PUT", "DEL", "PATCH"];

if (action === "edit") {
if (Array.isArray(contextApis)) {
Expand Down
39 changes: 36 additions & 3 deletions src/widgets/APITree/APITree.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ function APITree() {
expandList,
rightClickMethod,
errors,
theme
theme,
select,
handleResourceMenu
)}
</TreeView>

Expand Down Expand Up @@ -239,7 +241,9 @@ export const compile = (
expandList,
rightClickMethod,
errors,
theme
theme,
select,
handleResourceMenu
) => {
if (apiData.length !== 0) {
const groupedByPath = apiData.reduce((acc, endpoint) => {
Expand Down Expand Up @@ -347,11 +351,40 @@ export const compile = (
const childItems = children ? renderTree(children) : [];
expandList.push(path);

const handleResourceClick = (event) => {
event.stopPropagation();

if (methods.length > 0) {
const firstMethod = methods[0];
const payload = {
path: firstMethod.path,
method: firstMethod.method,
};
const hash = window.btoa(JSON.stringify(payload));
select(hash);
}
};

const handleResourceContextMenu = (event) => {
event.preventDefault();
handleResourceClick(event);
handleResourceMenu(event);
};

return (
<TreeItem
key={path}
nodeId={path}
label={<div className="path">{path}</div>}
label={
<div
className="path"
onClick={(e) => e.stopPropagation()}
onContextMenu={handleResourceContextMenu}
style={{ cursor: "default" }}
>
{path}
</div>
}
children={[...methodItems, ...childItems]}
collapseIcon={<ArrowIcon down />}
expandIcon={<ArrowIcon right />}
Expand Down
24 changes: 17 additions & 7 deletions src/widgets/ResourceMenu/ResourceMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ const ResourceMenu = (props) => {
};

const deleteResource = () => {
selectPath();
const { pages } = state;
dispatch({
type: "DELETE_RESOURCE",
payload: { path: pages.api.selected.path },
});
handleClose();
setOpen(false);
Expand All @@ -78,13 +79,19 @@ const ResourceMenu = (props) => {
setAlertMessage("Root path cannot be deleted");
handleClose();
} else {
const selectedPath = state.pages.api.selected.path;
const deleteList = state.specification.api
.filter(
(item) =>
item.path.startsWith(selectedPath) && item.path !== selectedPath
)
.map((item) => item.path)
.filter((path, index, self) => self.indexOf(path) === index);

resourceRef.current = {
deleteAdress: state.pages.api.selected,
deleteList: Object.keys(state.specification.api).filter((item) => {
return item.includes(state.pages.api.selected.path);
}),
deleteAdress: selectedPath,
deleteList: deleteList,
};

handleClose();
setOpen(true);
}
Expand Down Expand Up @@ -138,7 +145,10 @@ const ResourceMenu = (props) => {
<Typography sx={styles.menuItemText}>Method</Typography>
</MenuItem>
<Divider />
<MenuItem onClick={handleResourceDeleteDialog}>
<MenuItem
onClick={handleResourceDeleteDialog}
disabled={state.pages.api.selected?.path === "/"}
>
<DeleteIcon />
<Typography sx={styles.menuItemText}>Delete</Typography>
</MenuItem>
Expand Down

0 comments on commit ea53625

Please sign in to comment.