Skip to content

Commit 3ff0288

Browse files
brian2wBrian Wang
and
Brian Wang
authored
[WEB-67] [CMS] rename redux function (#355)
* began implementation of deleteFileEntity reducer * started attempting to fix infinite loop issue when calling delete action * fixed infinite looping of delete action and reducer * changed delete file submit modal * changed file access to double click and made files selectable for delete * changed name of button from delete file to delete file/folder * changed data-anchor to fix test failing * added rename saga middleware so name is updated in the backend as well as frontend --------- Co-authored-by: Brian Wang <[email protected]>
1 parent c89c9c9 commit 3ff0288

File tree

13 files changed

+1391
-1425
lines changed

13 files changed

+1391
-1425
lines changed

frontend/package-lock.json

Lines changed: 154 additions & 288 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/src/packages/dashboard/Dashboard.tsx

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
import React, { useEffect, useState } from "react";
2-
import { useDispatch } from "react-redux";
3-
import styled from "styled-components";
4-
import { Breadcrumbs, Link } from "@mui/material";
1+
import React, { useEffect, useState } from 'react';
2+
import { useDispatch } from 'react-redux';
3+
import styled from 'styled-components';
4+
import { Breadcrumbs, Link } from '@mui/material';
55

66
// local imports
7-
import SideBar from "src/packages/dashboard/components/SideBar/SideBar";
8-
import Renderer from "./components/FileRenderer/Renderer";
7+
import SideBar from 'src/packages/dashboard/components/SideBar/SideBar';
8+
import Renderer from './components/FileRenderer/Renderer';
99
import {
1010
initAction,
1111
traverseBackFolder,
1212
traverseIntoFolder,
13-
} from "./state/folders/actions";
14-
import ConfirmationWindow from "./components/ConfirmationModal/ConfirmationWindow";
15-
import Directory from "./components/Directory";
16-
import { getFolderState } from "./api/helpers";
13+
} from './state/folders/actions';
14+
import ConfirmationWindow from './components/ConfirmationModal/ConfirmationWindow';
15+
import Directory from './components/Directory';
16+
import { getFolderState } from './api/helpers';
1717

1818
const Container = styled.div`
1919
display: flex;
@@ -30,12 +30,15 @@ const FlexWrapper = styled.div`
3030
export default function Dashboard() {
3131
const [isOpen, setOpen] = useState(true);
3232

33-
const [modalState, setModalState] = useState<{ open: boolean; type: string }>(
34-
{
35-
open: false,
36-
type: "",
37-
}
38-
);
33+
const [modalState, setModalState] = useState<{
34+
open: boolean;
35+
selectedFile: string;
36+
type: string;
37+
}>({
38+
open: false,
39+
selectedFile: '',
40+
type: '',
41+
});
3942

4043
const [selectedFile, setSelectedFile] = useState<string | null>(null);
4144
const parentFolder = getFolderState().parentFolder;
@@ -54,7 +57,7 @@ export default function Dashboard() {
5457
isOpen={isOpen}
5558
setOpen={setOpen}
5659
/>
57-
<FlexWrapper style={{ left: isOpen ? "0px" : "-250px" }}>
60+
<FlexWrapper style={{ left: isOpen ? '0px' : '-250px' }}>
5861
<Directory />
5962
<Renderer
6063
selectedFile={selectedFile}

frontend/src/packages/dashboard/api/index.ts

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { toFileOrFolder } from "./helpers";
2-
import { JSONFileFormat } from "./types";
1+
import { toFileOrFolder } from './helpers';
2+
import { JSONFileFormat } from './types';
33

4-
const DEFAULT_OWNER_GROUP = "1";
4+
const DEFAULT_OWNER_GROUP = '1';
55

66
// Given a file ID (if no ID is provided root is assumed), returns
77
// a FileFormat of that file from the backend
88
export async function getFolder(id?: string) {
9-
const ending = id === undefined ? "" : `?EntityID=${id}`;
9+
const ending = id === undefined ? '' : `?EntityID=${id}`;
1010
const folder_resp = await fetch(`/api/filesystem/info${ending}`);
1111

1212
if (!folder_resp.ok) {
@@ -44,13 +44,13 @@ export const newFile = async (
4444
): Promise<string> => {
4545
// This isn't attached to the parent folder yet,
4646
// TODO: patch once auth is finished
47-
const create_resp = await fetch("/api/filesystem/create", {
48-
method: "POST",
47+
const create_resp = await fetch('/api/filesystem/create', {
48+
method: 'POST',
4949
body: new URLSearchParams({
5050
LogicalName: name,
5151
Parent: parentID.toString(),
5252
OwnerGroup: DEFAULT_OWNER_GROUP,
53-
IsDocument: "true",
53+
IsDocument: 'true',
5454
}),
5555
});
5656

@@ -70,13 +70,13 @@ export const newFolder = async (
7070
parentID: string
7171
): Promise<string> => {
7272
// TODO: patch once auth is finished
73-
const create_resp = await fetch("/api/filesystem/create", {
74-
method: "POST",
73+
const create_resp = await fetch('/api/filesystem/create', {
74+
method: 'POST',
7575
body: new URLSearchParams({
7676
LogicalName: name,
7777
Parent: parentID.toString(),
7878
OwnerGroup: DEFAULT_OWNER_GROUP,
79-
IsDocument: "false",
79+
IsDocument: 'false',
8080
}),
8181
});
8282

@@ -87,3 +87,43 @@ export const newFolder = async (
8787
const response = await create_resp.json();
8888
return response.Response.NewID;
8989
};
90+
91+
export const renameFileEntity = async (
92+
fileEntityID: string,
93+
fileEntityNewName: string
94+
): Promise<void> => {
95+
const rename_resp = await fetch('/api/filesystem/rename', {
96+
method: 'POST',
97+
body: new URLSearchParams({
98+
EntityID: fileEntityID,
99+
NewName: fileEntityNewName,
100+
}),
101+
});
102+
103+
if (!rename_resp.ok) {
104+
const message = `An error has occured: ${rename_resp.status}`;
105+
throw new Error(message);
106+
}
107+
const response = await rename_resp.json();
108+
109+
console.log(response);
110+
return;
111+
};
112+
113+
export const deleteFileEntity = async (fileEntityID: string): Promise<void> => {
114+
const delete_resp = await fetch('/api/filesystem/delete', {
115+
method: 'POST',
116+
body: new URLSearchParams({
117+
EntityID: fileEntityID,
118+
}),
119+
});
120+
121+
if (!delete_resp.ok) {
122+
const message = `An error has occured: ${delete_resp.status}`;
123+
throw new Error(message);
124+
}
125+
const response = await delete_resp.json();
126+
127+
console.log(response);
128+
return;
129+
};
Lines changed: 125 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,146 @@
1-
import React, { useEffect, useState } from "react";
2-
import styled from "styled-components";
3-
import { Modal, Typography, TextField, Box } from "@mui/material";
4-
import { useDispatch } from "react-redux";
1+
import React, { useEffect, useState } from 'react';
2+
import styled from 'styled-components';
3+
import { Modal, Typography, TextField, Box } from '@mui/material';
4+
import { useDispatch } from 'react-redux';
55

66
// local imports
7-
import Button from "../../../../cse-ui-kit/buttons/Button";
7+
import Button from '../../../../cse-ui-kit/buttons/Button';
88
import {
9-
addItemAction,
10-
AddPayloadType,
11-
} from "src/packages/dashboard/state/folders/actions";
12-
import { getFolderState } from "../../api/helpers";
9+
addItemAction,
10+
AddPayloadType,
11+
deleteFileEntityAction,
12+
DeletePayloadType,
13+
} from 'src/packages/dashboard/state/folders/actions';
14+
import { getFolderState } from '../../api/helpers';
1315

1416
type Props = {
15-
open: boolean;
16-
modalState: { open: boolean; type: string };
17-
setModalState: (flag: { open: boolean; type: string }) => void;
17+
open: boolean;
18+
modalState: { open: boolean; selectedFile: string; type: string };
19+
setModalState: (flag: {
20+
open: boolean;
21+
selectedFile: string;
22+
type: string;
23+
}) => void;
1824
};
1925

2026
const Container = styled.div`
21-
position: absolute;
22-
top: 50%;
23-
left: 50%;
24-
transform: translate(-50%, -50%);
27+
position: absolute;
28+
top: 50%;
29+
left: 50%;
30+
transform: translate(-50%, -50%);
2531
26-
width: 500px;
27-
height: 200px;
28-
background: white;
29-
border-radius: 20px;
32+
width: 500px;
33+
height: 200px;
34+
background: white;
35+
border-radius: 20px;
3036
31-
display: flex;
32-
flex-direction: column;
33-
justify-content: center;
34-
align-items: center;
35-
grid-gap: 20px;
37+
display: flex;
38+
flex-direction: column;
39+
justify-content: center;
40+
align-items: center;
41+
grid-gap: 20px;
3642
`;
3743

3844
export default function ConfirmationWindow({
39-
open,
40-
modalState,
41-
setModalState,
45+
open,
46+
modalState,
47+
setModalState,
4248
}: Props) {
43-
const dispatch = useDispatch();
44-
const [inputValue, setInputValue] = useState<string>("");
45-
const folderState = getFolderState();
49+
const dispatch = useDispatch();
50+
const [inputValue, setInputValue] = useState<string>('');
51+
const folderState = getFolderState();
4652

47-
useEffect(() => {
48-
setInputValue("");
49-
}, [modalState]);
53+
useEffect(() => {
54+
setInputValue('');
55+
}, [modalState]);
5056

51-
const handleSubmit = () => {
52-
switch (modalState.type) {
53-
case "folder": {
54-
const folderPayload: AddPayloadType = {
55-
name: inputValue,
56-
type: "Folder",
57-
parentId: folderState.parentFolder,
58-
};
59-
dispatch(addItemAction(folderPayload));
60-
break;
61-
}
62-
case "file": {
63-
const filePayload: AddPayloadType = {
64-
name: inputValue,
65-
type: "File",
66-
parentId: folderState.parentFolder,
67-
};
68-
dispatch(addItemAction(filePayload));
69-
break;
70-
}
71-
}
57+
const handleSubmit = () => {
58+
switch (modalState.type) {
59+
case 'folder': {
60+
const folderPayload: AddPayloadType = {
61+
name: inputValue,
62+
type: 'Folder',
63+
parentId: folderState.parentFolder,
64+
};
65+
dispatch(addItemAction(folderPayload));
66+
break;
67+
}
68+
case 'file': {
69+
const filePayload: AddPayloadType = {
70+
name: inputValue,
71+
type: 'File',
72+
parentId: folderState.parentFolder,
73+
};
74+
dispatch(addItemAction(filePayload));
75+
break;
76+
}
77+
case 'delete': {
78+
const folderPayload: DeletePayloadType = {
79+
id: modalState.selectedFile,
80+
};
81+
dispatch(deleteFileEntityAction(folderPayload));
82+
break;
83+
}
84+
}
7285

73-
setModalState({
74-
open: false,
75-
type: "",
76-
});
77-
};
86+
setModalState({
87+
open: false,
88+
selectedFile: '',
89+
type: '',
90+
});
91+
};
7892

79-
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
80-
const value = e.target.value;
81-
setInputValue(value);
82-
};
93+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
94+
const value = e.target.value;
95+
setInputValue(value);
96+
};
8397

84-
const handleKeyDown = (e: React.KeyboardEvent) => {
85-
if (e.key === 'Enter') {
86-
handleSubmit();
87-
}
88-
}
98+
const handleKeyDown = (e: React.KeyboardEvent) => {
99+
if (e.key === 'Enter') {
100+
handleSubmit();
101+
}
102+
};
89103

90-
return (
91-
<Modal
92-
open={open}
93-
onClose={() => {
94-
setModalState({
95-
open: false,
96-
type: "",
97-
});
98-
}}
99-
>
100-
<Container data-anchor="ConfirmationWindow">
101-
<Typography variant="h5">Choose your {modalState.type} name</Typography>
102-
<Box display="flex" alignItems="center">
103-
<TextField
104-
value={inputValue}
105-
onChange={handleChange}
106-
onKeyDown={handleKeyDown}
107-
sx={{ marginRight: "10px" }}
108-
/>
109-
<Button background="#73EEDC" onClick={handleSubmit}>
110-
submit
111-
</Button>
112-
</Box>
113-
</Container>
114-
</Modal>
115-
);
104+
return (
105+
<Modal
106+
open={open}
107+
onClose={() => {
108+
setModalState({
109+
open: false,
110+
selectedFile: '',
111+
type: '',
112+
});
113+
}}
114+
>
115+
{modalState.type !== 'delete' ? (
116+
<Container data-anchor="ConfirmationWindow">
117+
<Typography variant="h5">
118+
Choose your {modalState.type} name
119+
</Typography>
120+
<Box display="flex" alignItems="center">
121+
<TextField
122+
value={inputValue}
123+
onChange={handleChange}
124+
onKeyDown={handleKeyDown}
125+
sx={{ marginRight: '10px' }}
126+
/>
127+
<Button background="#73EEDC" onClick={handleSubmit}>
128+
submit
129+
</Button>
130+
</Box>
131+
</Container>
132+
) : (
133+
<Container data-anchor="ConfirmationWindow">
134+
<Typography variant="h5">
135+
Are you sure you want to delete?
136+
</Typography>
137+
<Box display="flex" alignItems="center">
138+
<Button background="#73EEDC" onClick={handleSubmit}>
139+
continue
140+
</Button>
141+
</Box>
142+
</Container>
143+
)}
144+
</Modal>
145+
);
116146
}

0 commit comments

Comments
 (0)