Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: rename file #102

Merged
merged 5 commits into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ const FileBrowser = ({ readOnly = false, onCreateManually, className }) => {
});
};

const handleRenameFolder = (newName, folderId) => {
const handleRenameItem = (newName, itemId) => {
filesDispatch({
type: 'renameFolder',
folderId,
type: 'renameItem',
itemId,
newName,
});
};
Expand Down Expand Up @@ -207,7 +207,7 @@ const FileBrowser = ({ readOnly = false, onCreateManually, className }) => {
onAddFile={!readOnly ? handleAddFile : noop}
onAddFolder={!readOnly ? handleAddFolder : noop}
onDropFile={!readOnly ? handleDropFile : noop}
onRenameFolder={!readOnly ? handleRenameFolder : noop}
onRenameItem={!readOnly ? handleRenameItem : noop}
onItemDelete={!readOnly ? handleDeleteItem : noop}
onOpenFile={handleOpenFile}
onDragStart={!readOnly ? handleDragStart : noop}
Expand Down
51 changes: 39 additions & 12 deletions templates/frontend/src/components/shared/file-browser/file/file.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import classNames from 'classnames/bind';
import { useEffect, useRef, useState } from 'react';
import { useEffect, useRef, useState, useCallback } from 'react';

import Dropdown from 'components/shared/dropdown';
import RenameItemModal from 'components/shared/file-browser/rename-item-modal';
import { useFiles } from 'contexts/files-provider';
import CloseSvg from 'icons/close.inline.svg';
import DotsIcon from 'icons/dots.inline.svg';
import { getIconByFilename } from 'utils/language';

import DeleteFileModal from '../delete-file-modal';
Expand All @@ -21,6 +23,7 @@ const File = ({
onDelete,
onDragStart,
onDragEnd,
onRenameItem,
level,
readOnly,
}) => {
Expand All @@ -31,6 +34,7 @@ const File = ({
} = useFiles();

const [isDeleteFileModalOpen, setIsDeleteFileModalOpen] = useState(false);
const [isRenameItemModalOpen, setIsRenameItemModalOpen] = useState(false);

useEffect(() => {
const fileElem = fileRef.current;
Expand All @@ -54,12 +58,6 @@ const File = ({
onDelete(file.id);
};

const handleDeleteClick = (evt) => {
evt.preventDefault();
evt.stopPropagation();
setIsDeleteFileModalOpen(true);
};

const handleDragStart = (evt) => {
onOpen(null);
evt.preventDefault();
Expand All @@ -68,6 +66,20 @@ const File = ({
};

const Icon = getIconByFilename(file.data.name);
const menuItems = [
{
text: 'Rename',
onClick: () => setIsRenameItemModalOpen(true),
},
{
text: 'Delete',
onClick: () => setIsDeleteFileModalOpen(true),
theme: 'danger',
},
];

const handleCloseDeleteFileModalClick = useCallback(() => setIsDeleteFileModalOpen(false), []);
const handleCloseRenameFileModalClick = useCallback(() => setIsRenameItemModalOpen(false), []);

return (
<div
Expand All @@ -83,18 +95,33 @@ const File = ({
<DeleteFileModal
name={file.data.name}
isOpen={isDeleteFileModalOpen}
onClose={() => setIsDeleteFileModalOpen(false)}
onClose={handleCloseDeleteFileModalClick}
onSave={handleDelete}
/>
)}
{isRenameItemModalOpen && (
<RenameItemModal
label="file"
name={file.data.name}
isOpen={isRenameItemModalOpen}
onClose={handleCloseRenameFileModalClick}
onSave={(newName) => onRenameItem(newName, file.id)}
/>
)}
<div className={cx('file-icon')} style={{ left: 7 + 25 * level }}>
<Icon />
</div>
{file.data.name}
{!readOnly && (
<button className={cx('button-delete')} onClick={handleDeleteClick}>
<CloseSvg className={cx('icon')} />
</button>
<Dropdown
menuItems={menuItems}
className={cx('options')}
position="top-right"
menuClassName={cx('options-menu')}
stopPropagation
>
<DotsIcon className={cx('options-icon')} />
</Dropdown>
)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@

&:hover {
background-color: $color-secondary-black;
border-radius: 2px;

& .button-delete {
.options {
visibility: visible;
opacity: 1;
}
}

Expand Down Expand Up @@ -72,3 +74,38 @@
}
}
}

.options {
position: absolute;
top: 50%;
right: 5px;
z-index: 1;
display: flex;
align-items: center;
justify-content: flex-end;
height: 12px;
padding-top: 7px;
padding-right: 10px;
padding-bottom: 7px;
padding-left: 10px;
margin-left: auto;
cursor: pointer;
visibility: hidden;
opacity: 0;
transform: translateY(-50%);

&:hover {
circle {
fill: $color-white;
}
}
}

.options-icon {
height: 15px;
fill: $color-grey;
}

.options-menu {
min-width: 100px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Dropdown from 'components/shared/dropdown';
import AddFileModal from 'components/shared/file-browser/add-file-modal';
import AddFolderModal from 'components/shared/file-browser/add-folder-modal';
import DeleteFolderModal from 'components/shared/file-browser/delete-folder-modal';
import RenameFolderModal from 'components/shared/file-browser/rename-folder-modal';
import RenameItemModal from 'components/shared/file-browser/rename-item-modal';
import TreeRecursive from 'components/shared/file-browser/tree-recursive';
import ArrowSvg from 'icons/arrow-down.inline.svg';
import DotsIcon from 'icons/dots.inline.svg';
Expand All @@ -21,7 +21,7 @@ const Folder = ({
onOpenFile,
onAddFile,
onAddFolder,
onRenameFolder,
onRenameItem,
onDragStart,
onDragEnd,
level,
Expand Down Expand Up @@ -73,7 +73,7 @@ const Folder = ({

const [isAddFileModalOpen, setIsAddFileModalOpen] = useState(false);
const [isAddFolderModalOpen, setIsAddFolderModalOpen] = useState(false);
const [isRenameFolderModalOpen, setIsRenameFolderModalOpen] = useState(false);
const [isRenameItemModalOpen, setIsRenameItemModalOpen] = useState(false);
const [isDeleteFolderModalOpen, setIsDeleteFolderModalOpen] = useState(false);

const menuItems = [
Expand All @@ -87,7 +87,7 @@ const Folder = ({
},
{
text: 'Rename',
onClick: () => setIsRenameFolderModalOpen(true),
onClick: () => setIsRenameItemModalOpen(true),
},
{
text: 'Delete',
Expand All @@ -96,6 +96,22 @@ const Folder = ({
},
];

const handleCloseRenameItemModalClick = useCallback(() => {
setIsRenameItemModalOpen(false);
}, []);

const handleCloseAddFolderModalClick = useCallback(() => {
setIsAddFolderModalOpen(false);
}, []);

const handleCloseDeleteFolderModalClick = useCallback(() => {
setIsDeleteFolderModalOpen(false);
}, []);

const handleCloseAddFileModalClick = useCallback(() => {
setIsAddFileModalOpen(false);
}, []);

return (
<div
ref={folderRef}
Expand Down Expand Up @@ -132,30 +148,31 @@ const Folder = ({
{isAddFileModalOpen && (
<AddFileModal
isOpen={isAddFileModalOpen}
onClose={() => setIsAddFileModalOpen(false)}
onClose={handleCloseAddFileModalClick}
onSave={(fileName) => onAddFile(fileName, folder.id)}
/>
)}
{isAddFolderModalOpen && (
<AddFolderModal
isOpen={isAddFolderModalOpen}
onClose={() => setIsAddFolderModalOpen(false)}
onClose={handleCloseAddFolderModalClick}
onSave={(folderName) => onAddFolder(folderName, folder.id)}
/>
)}
{isRenameFolderModalOpen && (
<RenameFolderModal
{isRenameItemModalOpen && (
<RenameItemModal
label="folder"
name={folder.data.name}
isOpen={isRenameFolderModalOpen}
onClose={() => setIsRenameFolderModalOpen(false)}
onSave={(newName) => onRenameFolder(newName, folder.id)}
isOpen={isRenameItemModalOpen}
onClose={handleCloseRenameItemModalClick}
onSave={(newName) => onRenameItem(newName, folder.id)}
/>
)}
{isDeleteFolderModalOpen && (
<DeleteFolderModal
name={folder.data.name}
isOpen={isDeleteFolderModalOpen}
onClose={() => setIsDeleteFolderModalOpen(false)}
onClose={handleCloseDeleteFolderModalClick}
onSave={() => onDelete(folder.id)}
/>
)}
Expand All @@ -174,7 +191,7 @@ const Folder = ({
onAddFile={onAddFile}
onAddFolder={onAddFolder}
onOpenFile={onOpenFile}
onRenameFolder={onRenameFolder}
onRenameItem={onRenameItem}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
/>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './rename-item-modal';
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Input from 'components/shared/input';
import Modal from 'components/shared/modal';
import ModalPortal from 'components/shared/modal-portal';

import styles from './rename-folder-modal.module.scss';
import styles from './rename-item-modal.module.scss';

const schema = yup.object().shape({
newName: yup
Expand All @@ -23,8 +23,8 @@ const schema = yup.object().shape({

const cx = classNames.bind(styles);

const RenameFolderModal = (props) => {
const { name, isOpen, onClose, onSave } = props;
const RenameItemModal = (props) => {
const { name, isOpen, onClose, onSave, label } = props;

const { register, handleSubmit, clearErrors, errors } = useForm({
defaultValues: { newName: name },
Expand All @@ -40,10 +40,10 @@ const RenameFolderModal = (props) => {

return (
<ModalPortal>
<Modal theme="grey" title="Rename folder" isOpen={isOpen} onRequestClose={onClose}>
<Modal theme="grey" title={`Rename ${label}`} isOpen={isOpen} onRequestClose={onClose}>
<form onSubmit={handleSubmit(onSubmit)}>
<Input
label="New folder name"
label={`New ${label} name`}
name="newName"
register={register}
error={errors.newName?.message}
Expand All @@ -62,17 +62,17 @@ const RenameFolderModal = (props) => {
);
};

RenameFolderModal.propTypes = {
RenameItemModal.propTypes = {
name: PropTypes.string.isRequired,
isOpen: PropTypes.bool,
onClose: PropTypes.func,
onSave: PropTypes.func,
};

RenameFolderModal.defaultProps = {
RenameItemModal.defaultProps = {
isOpen: false,
onClose: () => {},
onSave: () => {},
};

export default RenameFolderModal;
export default RenameItemModal;
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const TreeRecursive = ({
onOpenFile,
onAddFile,
onAddFolder,
onRenameFolder,
onRenameItem,
onDragStart,
onDragEnd,
level,
Expand All @@ -37,6 +37,7 @@ const TreeRecursive = ({
onOpen={onOpenFile}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
onRenameItem={onRenameItem}
/>
);
}
Expand All @@ -51,7 +52,7 @@ const TreeRecursive = ({
onAddFile={onAddFile}
onAddFolder={onAddFolder}
onOpenFile={onOpenFile}
onRenameFolder={onRenameFolder}
onRenameItem={onRenameItem}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
/>
Expand Down
6 changes: 3 additions & 3 deletions templates/frontend/src/contexts/files-provider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useContext, useReducer } from 'react';
import {
addItem,
moveItem,
renameFolder,
renameItem,
deleteItem,
changeFileContent,
changeFileLanguage,
Expand Down Expand Up @@ -37,11 +37,11 @@ export const filesReducer = (state, action) => {
hasChangedFiles: true,
...moveItem({ files: state.files, item: action.item, newFolderId: action.newFolderId }),
};
case 'renameFolder':
case 'renameItem':
return {
...state,
hasChangedFiles: true,
...renameFolder({ files: state.files, folderId: action.folderId, newName: action.newName }),
...renameItem({ files: state.files, itemId: action.itemId, newName: action.newName }),
};
case 'deleteItem':
return {
Expand Down
Loading