mirror of
https://github.com/plankanban/planka.git
synced 2025-07-27 17:19:43 +02:00
Move from prettier-eslint to eslint-plugin-prettier, update dependencies
This commit is contained in:
parent
1f43d4f214
commit
45bde7e7c0
254 changed files with 5539 additions and 5170 deletions
|
@ -1,18 +1,14 @@
|
|||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Button, Form, Header, Modal,
|
||||
} from 'semantic-ui-react';
|
||||
import { Button, Form, Header, Modal } from 'semantic-ui-react';
|
||||
import { Input } from '../../lib/custom-ui';
|
||||
|
||||
import { useForm } from '../../hooks';
|
||||
|
||||
import styles from './AddProjectModal.module.css';
|
||||
|
||||
const AddProjectModal = React.memo(({
|
||||
defaultData, isSubmitting, onCreate, onClose,
|
||||
}) => {
|
||||
const AddProjectModal = React.memo(({ defaultData, isSubmitting, onCreate, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [data, handleFieldChange] = useForm(() => ({
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import isEmail from 'validator/lib/isEmail';
|
||||
import React, {
|
||||
useCallback, useEffect, useMemo, useRef,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Form, Message } from 'semantic-ui-react';
|
||||
|
@ -13,7 +11,7 @@ import { useForm } from '../../hooks';
|
|||
|
||||
import styles from './AddUserPopup.module.css';
|
||||
|
||||
const createMessage = (error) => {
|
||||
const createMessage = error => {
|
||||
if (!error) {
|
||||
return error;
|
||||
}
|
||||
|
@ -32,9 +30,7 @@ const createMessage = (error) => {
|
|||
};
|
||||
|
||||
const AddUserPopup = React.memo(
|
||||
({
|
||||
defaultData, isSubmitting, error, onCreate, onMessageDismiss, onClose,
|
||||
}) => {
|
||||
({ defaultData, isSubmitting, error, onCreate, onMessageDismiss, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
const wasSubmitting = usePrevious(isSubmitting);
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useImperativeHandle, useRef, useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Form, Input } from 'semantic-ui-react';
|
||||
|
@ -44,7 +42,7 @@ const AddList = React.forwardRef(({ children, onCreate }, ref) => {
|
|||
}, [open]);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
if (event.key === 'Escape') {
|
||||
close();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import { ReactComponent as PlusMathIcon } from '../../assets/images/plus-math-ic
|
|||
|
||||
import styles from './Board.module.css';
|
||||
|
||||
const parseDndId = (dndId) => dndId.split(':')[1];
|
||||
const parseDndId = dndId => dndId.split(':')[1];
|
||||
|
||||
const Board = React.memo(
|
||||
({
|
||||
|
@ -41,12 +41,10 @@ const Board = React.memo(
|
|||
}, []);
|
||||
|
||||
const handleDragEnd = useCallback(
|
||||
({
|
||||
draggableId, type, source, destination,
|
||||
}) => {
|
||||
({ draggableId, type, source, destination }) => {
|
||||
if (
|
||||
!destination
|
||||
|| (source.droppableId === destination.droppableId && source.index === destination.index)
|
||||
!destination ||
|
||||
(source.droppableId === destination.droppableId && source.index === destination.index)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -26,14 +26,14 @@ const Filter = React.memo(
|
|||
const [t] = useTranslation();
|
||||
|
||||
const handleUserRemoveClick = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onUserRemove(id);
|
||||
},
|
||||
[onUserRemove],
|
||||
);
|
||||
|
||||
const handleLabelRemoveClick = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onLabelRemove(id);
|
||||
},
|
||||
[onLabelRemove],
|
||||
|
@ -44,7 +44,7 @@ const Filter = React.memo(
|
|||
<span className={styles.filter}>
|
||||
<ProjectMembershipsPopup
|
||||
items={allProjectMemberships}
|
||||
currentUserIds={users.map((user) => user.id)}
|
||||
currentUserIds={users.map(user => user.id)}
|
||||
title={t('common.filterByMembers', {
|
||||
context: 'title',
|
||||
})}
|
||||
|
@ -56,7 +56,7 @@ const Filter = React.memo(
|
|||
{users.length === 0 && <span className={styles.filterLabel}>{t('common.all')}</span>}
|
||||
</button>
|
||||
</ProjectMembershipsPopup>
|
||||
{users.map((user) => (
|
||||
{users.map(user => (
|
||||
<span key={user.id} className={styles.filterItem}>
|
||||
<User
|
||||
name={user.name}
|
||||
|
@ -70,7 +70,7 @@ const Filter = React.memo(
|
|||
<span className={styles.filter}>
|
||||
<LabelsPopup
|
||||
items={allLabels}
|
||||
currentIds={labels.map((label) => label.id)}
|
||||
currentIds={labels.map(label => label.id)}
|
||||
title={t('common.filterByLabels', {
|
||||
context: 'title',
|
||||
})}
|
||||
|
@ -85,7 +85,7 @@ const Filter = React.memo(
|
|||
{labels.length === 0 && <span className={styles.filterLabel}>{t('common.all')}</span>}
|
||||
</button>
|
||||
</LabelsPopup>
|
||||
{labels.map((label) => (
|
||||
{labels.map(label => (
|
||||
<span key={label.id} className={styles.filterItem}>
|
||||
<Label
|
||||
name={label.name}
|
||||
|
|
|
@ -18,9 +18,7 @@ import EditPopup from './EditPopup';
|
|||
import styles from './Boards.module.css';
|
||||
|
||||
const Boards = React.memo(
|
||||
({
|
||||
items, currentId, isEditable, onCreate, onUpdate, onMove, onDelete,
|
||||
}) => {
|
||||
({ items, currentId, isEditable, onCreate, onUpdate, onMove, onDelete }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleDragStart = useCallback(() => {
|
||||
|
@ -46,76 +44,78 @@ const Boards = React.memo(
|
|||
);
|
||||
|
||||
const handleDelete = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onDelete(id);
|
||||
},
|
||||
[onDelete],
|
||||
);
|
||||
|
||||
const renderItems = useCallback(
|
||||
(safeItems) => safeItems.map((item) => (
|
||||
<div key={item.id} className={styles.tabWrapper}>
|
||||
<div className={classNames(styles.tab, item.id === currentId && styles.tabActive)}>
|
||||
{item.isPersisted ? (
|
||||
<Link
|
||||
to={Paths.BOARDS.replace(':id', item.id)}
|
||||
title={item.name}
|
||||
className={styles.link}
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
) : (
|
||||
<span className={styles.link}>{item.name}</span>
|
||||
)}
|
||||
safeItems =>
|
||||
safeItems.map(item => (
|
||||
<div key={item.id} className={styles.tabWrapper}>
|
||||
<div className={classNames(styles.tab, item.id === currentId && styles.tabActive)}>
|
||||
{item.isPersisted ? (
|
||||
<Link
|
||||
to={Paths.BOARDS.replace(':id', item.id)}
|
||||
title={item.name}
|
||||
className={styles.link}
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
) : (
|
||||
<span className={styles.link}>{item.name}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)),
|
||||
)),
|
||||
[currentId],
|
||||
);
|
||||
|
||||
const renderEditableItems = useCallback(
|
||||
(safeItems) => safeItems.map((item, index) => (
|
||||
<Draggable
|
||||
key={item.id}
|
||||
draggableId={item.id}
|
||||
index={index}
|
||||
isDragDisabled={!item.isPersisted}
|
||||
>
|
||||
{({ innerRef, draggableProps, dragHandleProps }) => (
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
<div {...draggableProps} ref={innerRef} className={styles.tabWrapper}>
|
||||
<div className={classNames(styles.tab, item.id === currentId && styles.tabActive)}>
|
||||
{item.isPersisted ? (
|
||||
<Link
|
||||
{...dragHandleProps} // eslint-disable-line react/jsx-props-no-spreading
|
||||
to={Paths.BOARDS.replace(':id', item.id)}
|
||||
title={item.name}
|
||||
className={styles.link}
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
) : (
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
<span {...dragHandleProps} className={styles.link}>
|
||||
{item.name}
|
||||
</span>
|
||||
)}
|
||||
{item.isPersisted && (
|
||||
<EditPopup
|
||||
defaultData={pick(item, 'name')}
|
||||
onUpdate={(data) => handleUpdate(item.id, data)}
|
||||
onDelete={() => handleDelete(item.id)}
|
||||
>
|
||||
<Button className={classNames(styles.editButton, styles.target)}>
|
||||
<Icon fitted name="pencil" size="small" />
|
||||
</Button>
|
||||
</EditPopup>
|
||||
)}
|
||||
safeItems =>
|
||||
safeItems.map((item, index) => (
|
||||
<Draggable
|
||||
key={item.id}
|
||||
draggableId={item.id}
|
||||
index={index}
|
||||
isDragDisabled={!item.isPersisted}
|
||||
>
|
||||
{({ innerRef, draggableProps, dragHandleProps }) => (
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
<div {...draggableProps} ref={innerRef} className={styles.tabWrapper}>
|
||||
<div className={classNames(styles.tab, item.id === currentId && styles.tabActive)}>
|
||||
{item.isPersisted ? (
|
||||
<Link
|
||||
{...dragHandleProps} // eslint-disable-line react/jsx-props-no-spreading
|
||||
to={Paths.BOARDS.replace(':id', item.id)}
|
||||
title={item.name}
|
||||
className={styles.link}
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
) : (
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
<span {...dragHandleProps} className={styles.link}>
|
||||
{item.name}
|
||||
</span>
|
||||
)}
|
||||
{item.isPersisted && (
|
||||
<EditPopup
|
||||
defaultData={pick(item, 'name')}
|
||||
onUpdate={data => handleUpdate(item.id, data)}
|
||||
onDelete={() => handleDelete(item.id)}
|
||||
>
|
||||
<Button className={classNames(styles.editButton, styles.target)}>
|
||||
<Icon fitted name="pencil" size="small" />
|
||||
</Button>
|
||||
</EditPopup>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
)),
|
||||
)}
|
||||
</Draggable>
|
||||
)),
|
||||
[currentId, handleUpdate, handleDelete],
|
||||
);
|
||||
|
||||
|
|
|
@ -15,9 +15,7 @@ const StepTypes = {
|
|||
DELETE: 'DELETE',
|
||||
};
|
||||
|
||||
const EditStep = React.memo(({
|
||||
defaultData, onUpdate, onDelete, onClose,
|
||||
}) => {
|
||||
const EditStep = React.memo(({ defaultData, onUpdate, onDelete, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [data, handleFieldChange] = useForm(() => ({
|
||||
|
|
|
@ -70,7 +70,7 @@ const ActionsStep = React.memo(
|
|||
}, [openStep]);
|
||||
|
||||
const handleDueDateUpdate = useCallback(
|
||||
(dueDate) => {
|
||||
dueDate => {
|
||||
onUpdate({
|
||||
dueDate,
|
||||
});
|
||||
|
@ -79,7 +79,7 @@ const ActionsStep = React.memo(
|
|||
);
|
||||
|
||||
const handleTimerUpdate = useCallback(
|
||||
(timer) => {
|
||||
timer => {
|
||||
onUpdate({
|
||||
timer,
|
||||
});
|
||||
|
|
|
@ -49,7 +49,7 @@ const Card = React.memo(
|
|||
}, []);
|
||||
|
||||
const handleNameUpdate = useCallback(
|
||||
(newName) => {
|
||||
newName => {
|
||||
onUpdate({
|
||||
name: newName,
|
||||
});
|
||||
|
@ -65,7 +65,7 @@ const Card = React.memo(
|
|||
<>
|
||||
{labels.length > 0 && (
|
||||
<span className={styles.labels}>
|
||||
{labels.map((label) => (
|
||||
{labels.map(label => (
|
||||
<span key={label.id} className={classNames(styles.attachment, styles.attachmentLeft)}>
|
||||
<Label name={label.name} color={label.color} size="tiny" />
|
||||
</span>
|
||||
|
@ -101,7 +101,7 @@ const Card = React.memo(
|
|||
)}
|
||||
{users.length > 0 && (
|
||||
<span className={classNames(styles.attachments, styles.attachmentsRight)}>
|
||||
{users.map((user) => (
|
||||
{users.map(user => (
|
||||
<span key={user.id} className={classNames(styles.attachment, styles.attachmentRight)}>
|
||||
<User name={user.name} avatar={user.avatar} size="tiny" />
|
||||
</span>
|
||||
|
@ -136,9 +136,9 @@ const Card = React.memo(
|
|||
isPersisted,
|
||||
}}
|
||||
projectMemberships={allProjectMemberships}
|
||||
currentUserIds={users.map((user) => user.id)}
|
||||
currentUserIds={users.map(user => user.id)}
|
||||
labels={allLabels}
|
||||
currentLabelIds={labels.map((label) => label.id)}
|
||||
currentLabelIds={labels.map(label => label.id)}
|
||||
onNameEdit={handleNameEdit}
|
||||
onUpdate={onUpdate}
|
||||
onDelete={onDelete}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useImperativeHandle, useRef, useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
|
@ -52,7 +50,7 @@ const EditName = React.forwardRef(({ children, defaultValue, onUpdate }, ref) =>
|
|||
);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
event.preventDefault();
|
||||
|
|
|
@ -10,7 +10,7 @@ const Tasks = React.memo(({ items }) => {
|
|||
const [isOpened, toggleOpened] = useToggle();
|
||||
|
||||
const handleToggleClick = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
event.preventDefault();
|
||||
|
||||
toggleOpened();
|
||||
|
@ -18,7 +18,7 @@ const Tasks = React.memo(({ items }) => {
|
|||
[toggleOpened],
|
||||
);
|
||||
|
||||
const completedItems = items.filter((item) => item.isCompleted);
|
||||
const completedItems = items.filter(item => item.isCompleted);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -47,7 +47,7 @@ const Tasks = React.memo(({ items }) => {
|
|||
</div>
|
||||
{isOpened && (
|
||||
<ul className={styles.tasks}>
|
||||
{items.map((item) => (
|
||||
{items.map(item => (
|
||||
<li
|
||||
key={item.id}
|
||||
className={classNames(styles.task, item.isCompleted && styles.taskCompleted)}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Comment, Icon, Loader, Visibility,
|
||||
} from 'semantic-ui-react';
|
||||
import { Comment, Icon, Loader, Visibility } from 'semantic-ui-react';
|
||||
|
||||
import { ActionTypes } from '../../../constants/Enums';
|
||||
import AddComment from './AddComment';
|
||||
|
@ -32,7 +30,7 @@ const Actions = React.memo(
|
|||
);
|
||||
|
||||
const handleCommentDelete = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onCommentDelete(id);
|
||||
},
|
||||
[onCommentDelete],
|
||||
|
@ -53,26 +51,28 @@ const Actions = React.memo(
|
|||
<div className={styles.moduleHeader}>{t('common.actions')}</div>
|
||||
<div className={styles.wrapper}>
|
||||
<Comment.Group>
|
||||
{items.map((item) => (item.type === ActionTypes.COMMENT_CARD ? (
|
||||
<Item.Comment
|
||||
key={item.id}
|
||||
data={item.data}
|
||||
createdAt={item.createdAt}
|
||||
isPersisted={item.isPersisted}
|
||||
user={item.user}
|
||||
isEditable={isEditable}
|
||||
onUpdate={(data) => handleCommentUpdate(item.id, data)}
|
||||
onDelete={() => handleCommentDelete(item.id)}
|
||||
/>
|
||||
) : (
|
||||
<Item
|
||||
key={item.id}
|
||||
type={item.type}
|
||||
data={item.data}
|
||||
createdAt={item.createdAt}
|
||||
user={item.user}
|
||||
/>
|
||||
)))}
|
||||
{items.map(item =>
|
||||
item.type === ActionTypes.COMMENT_CARD ? (
|
||||
<Item.Comment
|
||||
key={item.id}
|
||||
data={item.data}
|
||||
createdAt={item.createdAt}
|
||||
isPersisted={item.isPersisted}
|
||||
user={item.user}
|
||||
isEditable={isEditable}
|
||||
onUpdate={data => handleCommentUpdate(item.id, data)}
|
||||
onDelete={() => handleCommentDelete(item.id)}
|
||||
/>
|
||||
) : (
|
||||
<Item
|
||||
key={item.id}
|
||||
type={item.type}
|
||||
data={item.data}
|
||||
createdAt={item.createdAt}
|
||||
user={item.user}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</Comment.Group>
|
||||
</div>
|
||||
{isFetching ? (
|
||||
|
|
|
@ -35,7 +35,7 @@ const AddComment = React.memo(({ onCreate }) => {
|
|||
}, [onCreate, data, setData]);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
if (event.ctrlKey && event.key === 'Enter') {
|
||||
submit();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import dequal from 'dequal';
|
||||
import React, {
|
||||
useCallback, useEffect, useImperativeHandle, useRef, useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
|
@ -59,7 +57,7 @@ const EditComment = React.forwardRef(({ children, defaultData, onUpdate }, ref)
|
|||
);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
if (event.ctrlKey && event.key === 'Enter') {
|
||||
submit();
|
||||
}
|
||||
|
|
|
@ -10,9 +10,7 @@ import User from '../../User';
|
|||
|
||||
import styles from './Item.module.css';
|
||||
|
||||
const Item = React.memo(({
|
||||
type, data, createdAt, user,
|
||||
}) => {
|
||||
const Item = React.memo(({ type, data, createdAt, user }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
let contentNode;
|
||||
|
|
|
@ -12,9 +12,7 @@ import DeletePopup from '../../DeletePopup';
|
|||
import styles from './ItemComment.module.css';
|
||||
|
||||
const ItemComment = React.memo(
|
||||
({
|
||||
data, createdAt, isPersisted, user, isEditable, onUpdate, onDelete,
|
||||
}) => {
|
||||
({ data, createdAt, isPersisted, user, isEditable, onUpdate, onDelete }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const editComment = useRef(null);
|
||||
|
|
|
@ -2,9 +2,7 @@ import React, { useCallback } from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Button, Grid, Icon, Modal,
|
||||
} from 'semantic-ui-react';
|
||||
import { Button, Grid, Icon, Modal } from 'semantic-ui-react';
|
||||
import { Markdown } from '../../lib/custom-ui';
|
||||
|
||||
import NameField from './NameField';
|
||||
|
@ -60,7 +58,7 @@ const CardModal = React.memo(
|
|||
const [t] = useTranslation();
|
||||
|
||||
const handleNameUpdate = useCallback(
|
||||
(newName) => {
|
||||
newName => {
|
||||
onUpdate({
|
||||
name: newName,
|
||||
});
|
||||
|
@ -69,7 +67,7 @@ const CardModal = React.memo(
|
|||
);
|
||||
|
||||
const handleDescriptionUpdate = useCallback(
|
||||
(newDescription) => {
|
||||
newDescription => {
|
||||
onUpdate({
|
||||
description: newDescription,
|
||||
});
|
||||
|
@ -78,7 +76,7 @@ const CardModal = React.memo(
|
|||
);
|
||||
|
||||
const handleDueDateUpdate = useCallback(
|
||||
(newDueDate) => {
|
||||
newDueDate => {
|
||||
onUpdate({
|
||||
dueDate: newDueDate,
|
||||
});
|
||||
|
@ -87,7 +85,7 @@ const CardModal = React.memo(
|
|||
);
|
||||
|
||||
const handleTimerUpdate = useCallback(
|
||||
(newTimer) => {
|
||||
newTimer => {
|
||||
onUpdate({
|
||||
timer: newTimer,
|
||||
});
|
||||
|
@ -101,8 +99,8 @@ const CardModal = React.memo(
|
|||
});
|
||||
}, [isSubscribed, onUpdate]);
|
||||
|
||||
const userIds = users.map((user) => user.id);
|
||||
const labelIds = labels.map((label) => label.id);
|
||||
const userIds = users.map(user => user.id);
|
||||
const labelIds = labels.map(label => label.id);
|
||||
|
||||
return (
|
||||
<Modal open closeIcon size="small" centered={false} onClose={onClose}>
|
||||
|
@ -128,7 +126,7 @@ const CardModal = React.memo(
|
|||
context: 'title',
|
||||
})}
|
||||
</div>
|
||||
{users.map((user) => (
|
||||
{users.map(user => (
|
||||
<span key={user.id} className={styles.attachment}>
|
||||
<ProjectMembershipsPopup
|
||||
items={allProjectMemberships}
|
||||
|
@ -162,7 +160,7 @@ const CardModal = React.memo(
|
|||
context: 'title',
|
||||
})}
|
||||
</div>
|
||||
{labels.map((label) => (
|
||||
{labels.map(label => (
|
||||
<span key={label.id} className={styles.attachment}>
|
||||
<LabelsPopup
|
||||
key={label.id}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useImperativeHandle, useRef, useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
|
@ -53,7 +51,7 @@ const EditDescription = React.forwardRef(({ children, defaultValue, onUpdate },
|
|||
}, [open]);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
if (event.ctrlKey && event.key === 'Enter') {
|
||||
submit();
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ const NameField = React.memo(({ defaultValue, onUpdate }) => {
|
|||
isFocused.current = true;
|
||||
}, []);
|
||||
|
||||
const handleKeyDown = useCallback((event) => {
|
||||
const handleKeyDown = useCallback(event => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useImperativeHandle, useRef, useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
|
@ -62,7 +60,7 @@ const Add = React.forwardRef(({ children, onCreate }, ref) => {
|
|||
}, [open]);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useImperativeHandle, useRef, useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
|
@ -52,7 +50,7 @@ const EditName = React.forwardRef(({ children, defaultValue, onUpdate }, ref) =>
|
|||
);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
|
||||
|
|
|
@ -8,9 +8,7 @@ import ActionsPopup from './ActionsPopup';
|
|||
|
||||
import styles from './Item.module.css';
|
||||
|
||||
const Item = React.memo(({
|
||||
name, isCompleted, isPersisted, onUpdate, onDelete,
|
||||
}) => {
|
||||
const Item = React.memo(({ name, isCompleted, isPersisted, onUpdate, onDelete }) => {
|
||||
const editName = useRef(null);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
|
@ -20,7 +18,7 @@ const Item = React.memo(({
|
|||
}, [isPersisted]);
|
||||
|
||||
const handleNameUpdate = useCallback(
|
||||
(newName) => {
|
||||
newName => {
|
||||
onUpdate({
|
||||
name: newName,
|
||||
});
|
||||
|
|
|
@ -8,9 +8,7 @@ import Add from './Add';
|
|||
|
||||
import styles from './Tasks.module.css';
|
||||
|
||||
const Tasks = React.memo(({
|
||||
items, onCreate, onUpdate, onDelete,
|
||||
}) => {
|
||||
const Tasks = React.memo(({ items, onCreate, onUpdate, onDelete }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleUpdate = useCallback(
|
||||
|
@ -21,13 +19,13 @@ const Tasks = React.memo(({
|
|||
);
|
||||
|
||||
const handleDelete = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onDelete(id);
|
||||
},
|
||||
[onDelete],
|
||||
);
|
||||
|
||||
const completedItems = items.filter((item) => item.isCompleted);
|
||||
const completedItems = items.filter(item => item.isCompleted);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -41,13 +39,13 @@ const Tasks = React.memo(({
|
|||
className={styles.progress}
|
||||
/>
|
||||
)}
|
||||
{items.map((item) => (
|
||||
{items.map(item => (
|
||||
<Item
|
||||
key={item.id}
|
||||
name={item.name}
|
||||
isCompleted={item.isCompleted}
|
||||
isPersisted={item.isPersisted}
|
||||
onUpdate={(data) => handleUpdate(item.id, data)}
|
||||
onUpdate={data => handleUpdate(item.id, data)}
|
||||
onDelete={() => handleDelete(item.id)}
|
||||
/>
|
||||
))}
|
||||
|
|
|
@ -5,9 +5,7 @@ import { Popup } from '../../lib/custom-ui';
|
|||
|
||||
import styles from './DeleteStep.module.css';
|
||||
|
||||
const DeleteStep = React.memo(({
|
||||
title, content, buttonContent, onConfirm, onBack,
|
||||
}) => (
|
||||
const DeleteStep = React.memo(({ title, content, buttonContent, onConfirm, onBack }) => (
|
||||
<>
|
||||
<Popup.Header onBack={onBack}>{title}</Popup.Header>
|
||||
<Popup.Content>
|
||||
|
|
|
@ -35,9 +35,7 @@ const FORMATS = {
|
|||
medium: 'longDateTime',
|
||||
};
|
||||
|
||||
const DueDate = React.memo(({
|
||||
value, size, isDisabled, onClick,
|
||||
}) => {
|
||||
const DueDate = React.memo(({ value, size, isDisabled, onClick }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const style = {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useMemo, useRef,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import DatePicker from 'react-datepicker';
|
||||
|
@ -12,9 +10,7 @@ import { useForm } from '../../hooks';
|
|||
|
||||
import styles from './EditDueDateStep.module.css';
|
||||
|
||||
const EditDueDateStep = React.memo(({
|
||||
defaultValue, onUpdate, onBack, onClose,
|
||||
}) => {
|
||||
const EditDueDateStep = React.memo(({ defaultValue, onUpdate, onBack, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [data, handleFieldChange, setData] = useForm(() => {
|
||||
|
@ -51,8 +47,8 @@ const EditDueDateStep = React.memo(({
|
|||
}, [data.date, t]);
|
||||
|
||||
const handleDatePickerChange = useCallback(
|
||||
(date) => {
|
||||
setData((prevData) => ({
|
||||
date => {
|
||||
setData(prevData => ({
|
||||
...prevData,
|
||||
date: t('format:date', {
|
||||
postProcess: 'formatDate',
|
||||
|
|
|
@ -7,13 +7,11 @@ import { useToggle } from '../../lib/hooks';
|
|||
import { Input, Popup } from '../../lib/custom-ui';
|
||||
|
||||
import { useForm } from '../../hooks';
|
||||
import {
|
||||
createTimer, getTimerParts, startTimer, stopTimer, updateTimer,
|
||||
} from '../../utils/timer';
|
||||
import { createTimer, getTimerParts, startTimer, stopTimer, updateTimer } from '../../utils/timer';
|
||||
|
||||
import styles from './EditTimerStep.module.css';
|
||||
|
||||
const createData = (timer) => {
|
||||
const createData = timer => {
|
||||
if (!timer) {
|
||||
return {
|
||||
hours: '0',
|
||||
|
@ -31,9 +29,7 @@ const createData = (timer) => {
|
|||
};
|
||||
};
|
||||
|
||||
const EditTimerStep = React.memo(({
|
||||
defaultValue, onUpdate, onBack, onClose,
|
||||
}) => {
|
||||
const EditTimerStep = React.memo(({ defaultValue, onUpdate, onBack, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
const [data, handleFieldChange, setData] = useForm(() => createData(defaultValue));
|
||||
const [isEditing, toggleEdit] = useToggle();
|
||||
|
@ -158,8 +154,8 @@ const EditTimerStep = React.memo(({
|
|||
</div>
|
||||
{isEditing && <Button positive content={t('action.save')} />}
|
||||
</Form>
|
||||
{!isEditing
|
||||
&& (defaultValue && defaultValue.startedAt ? (
|
||||
{!isEditing &&
|
||||
(defaultValue && defaultValue.startedAt ? (
|
||||
<Button positive content={t('action.stop')} icon="pause" onClick={handleStopClick} />
|
||||
) : (
|
||||
<Button positive content={t('action.start')} icon="play" onClick={handleStartClick} />
|
||||
|
|
|
@ -16,7 +16,7 @@ const NotificationsStep = React.memo(({ items, onDelete, onClose }) => {
|
|||
const [t] = useTranslation();
|
||||
|
||||
const handleDelete = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onDelete(id);
|
||||
},
|
||||
[onDelete],
|
||||
|
@ -77,28 +77,28 @@ const NotificationsStep = React.memo(({ items, onDelete, onClose }) => {
|
|||
<Popup.Header>{t('common.notifications')}</Popup.Header>
|
||||
<Popup.Content>
|
||||
{items.length > 0
|
||||
? items.map((item) => (
|
||||
<div key={item.id} className={styles.wrapper}>
|
||||
{item.card && item.action ? (
|
||||
<>
|
||||
<User
|
||||
name={item.action.user.name}
|
||||
avatar={item.action.user.avatar}
|
||||
size="large"
|
||||
/>
|
||||
<span className={styles.content}>{renderItemContent(item)}</span>
|
||||
</>
|
||||
) : (
|
||||
<div className={styles.deletedContent}>{t('common.cardOrActionAreDeleted')}</div>
|
||||
)}
|
||||
<Button
|
||||
type="button"
|
||||
icon="close"
|
||||
className={styles.button}
|
||||
onClick={() => handleDelete(item.id)}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
? items.map(item => (
|
||||
<div key={item.id} className={styles.wrapper}>
|
||||
{item.card && item.action ? (
|
||||
<>
|
||||
<User
|
||||
name={item.action.user.name}
|
||||
avatar={item.action.user.avatar}
|
||||
size="large"
|
||||
/>
|
||||
<span className={styles.content}>{renderItemContent(item)}</span>
|
||||
</>
|
||||
) : (
|
||||
<div className={styles.deletedContent}>{t('common.cardOrActionAreDeleted')}</div>
|
||||
)}
|
||||
<Button
|
||||
type="button"
|
||||
icon="close"
|
||||
className={styles.button}
|
||||
onClick={() => handleDelete(item.id)}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
: t('common.noUnreadNotifications')}
|
||||
</Popup.Content>
|
||||
</>
|
||||
|
|
|
@ -34,9 +34,7 @@ const STYLES = {
|
|||
},
|
||||
};
|
||||
|
||||
const Label = React.memo(({
|
||||
name, color, size, isDisabled, onClick,
|
||||
}) => {
|
||||
const Label = React.memo(({ name, color, size, isDisabled, onClick }) => {
|
||||
const style = {
|
||||
...STYLES[size],
|
||||
background: LabelColors.MAP[color],
|
||||
|
|
|
@ -16,9 +16,7 @@ const StepTypes = {
|
|||
DELETE: 'DELETE',
|
||||
};
|
||||
|
||||
const EditStep = React.memo(({
|
||||
defaultData, onUpdate, onDelete, onBack,
|
||||
}) => {
|
||||
const EditStep = React.memo(({ defaultData, onUpdate, onDelete, onBack }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [data, handleFieldChange] = useForm(() => ({
|
||||
|
|
|
@ -7,9 +7,7 @@ import LabelColors from '../../constants/LabelColors';
|
|||
|
||||
import styles from './Item.module.css';
|
||||
|
||||
const Item = React.memo(({
|
||||
name, color, isPersisted, isActive, onSelect, onDeselect, onEdit,
|
||||
}) => {
|
||||
const Item = React.memo(({ name, color, isPersisted, isActive, onSelect, onDeselect, onEdit }) => {
|
||||
const handleToggleClick = useCallback(() => {
|
||||
if (isActive) {
|
||||
onDeselect();
|
||||
|
|
|
@ -18,9 +18,7 @@ const StepTypes = {
|
|||
};
|
||||
|
||||
const LabelsStep = React.memo(
|
||||
({
|
||||
items, currentIds, title, onSelect, onDeselect, onCreate, onUpdate, onDelete, onBack,
|
||||
}) => {
|
||||
({ items, currentIds, title, onSelect, onDeselect, onCreate, onUpdate, onDelete, onBack }) => {
|
||||
const [t] = useTranslation();
|
||||
const [step, openStep, handleBack] = useSteps();
|
||||
|
||||
|
@ -29,7 +27,7 @@ const LabelsStep = React.memo(
|
|||
}, [openStep]);
|
||||
|
||||
const handleEdit = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
openStep(StepTypes.EDIT, {
|
||||
id,
|
||||
});
|
||||
|
@ -38,14 +36,14 @@ const LabelsStep = React.memo(
|
|||
);
|
||||
|
||||
const handleSelect = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onSelect(id);
|
||||
},
|
||||
[onSelect],
|
||||
);
|
||||
|
||||
const handleDeselect = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onDeselect(id);
|
||||
},
|
||||
[onDeselect],
|
||||
|
@ -59,7 +57,7 @@ const LabelsStep = React.memo(
|
|||
);
|
||||
|
||||
const handleDelete = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onDelete(id);
|
||||
},
|
||||
[onDelete],
|
||||
|
@ -70,13 +68,13 @@ const LabelsStep = React.memo(
|
|||
case StepTypes.ADD:
|
||||
return <AddStep onCreate={onCreate} onBack={handleBack} />;
|
||||
case StepTypes.EDIT: {
|
||||
const currentItem = items.find((item) => item.id === step.params.id);
|
||||
const currentItem = items.find(item => item.id === step.params.id);
|
||||
|
||||
if (currentItem) {
|
||||
return (
|
||||
<EditStep
|
||||
defaultData={pick(currentItem, ['name', 'color'])}
|
||||
onUpdate={(data) => handleUpdate(currentItem.id, data)}
|
||||
onUpdate={data => handleUpdate(currentItem.id, data)}
|
||||
onDelete={() => handleDelete(currentItem.id)}
|
||||
onBack={handleBack}
|
||||
/>
|
||||
|
@ -95,7 +93,7 @@ const LabelsStep = React.memo(
|
|||
<>
|
||||
<Popup.Header onBack={onBack}>{t(title)}</Popup.Header>
|
||||
<Popup.Content>
|
||||
{items.map((item) => (
|
||||
{items.map(item => (
|
||||
<Item
|
||||
key={item.id}
|
||||
name={item.name}
|
||||
|
|
|
@ -14,9 +14,7 @@ const StepTypes = {
|
|||
DELETE: 'DELETE',
|
||||
};
|
||||
|
||||
const ActionsStep = React.memo(({
|
||||
onNameEdit, onCardAdd, onDelete, onClose,
|
||||
}) => {
|
||||
const ActionsStep = React.memo(({ onNameEdit, onCardAdd, onDelete, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
const [step, openStep, handleBack] = useSteps();
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useImperativeHandle, useRef, useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
|
@ -62,7 +60,7 @@ const AddCard = React.forwardRef(({ children, onCreate }, ref) => {
|
|||
}, [open]);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
event.preventDefault();
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useImperativeHandle, useRef, useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
import { TextArea } from 'semantic-ui-react';
|
||||
|
@ -44,12 +42,12 @@ const EditName = React.forwardRef(({ children, defaultValue, onUpdate }, ref) =>
|
|||
[open, close],
|
||||
);
|
||||
|
||||
const handleFieldClick = useCallback((event) => {
|
||||
const handleFieldClick = useCallback(event => {
|
||||
event.stopPropagation();
|
||||
}, []);
|
||||
|
||||
const handleFieldKeyDown = useCallback(
|
||||
(event) => {
|
||||
event => {
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
event.preventDefault();
|
||||
|
|
|
@ -15,9 +15,7 @@ import { ReactComponent as PlusMathIcon } from '../../assets/images/plus-math-ic
|
|||
import styles from './List.module.css';
|
||||
|
||||
const List = React.memo(
|
||||
({
|
||||
id, index, name, isPersisted, cardIds, onUpdate, onDelete, onCardCreate,
|
||||
}) => {
|
||||
({ id, index, name, isPersisted, cardIds, onUpdate, onDelete, onCardCreate }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const addCard = useRef(null);
|
||||
|
@ -30,7 +28,7 @@ const List = React.memo(
|
|||
}, [isPersisted]);
|
||||
|
||||
const handleNameUpdate = useCallback(
|
||||
(newName) => {
|
||||
newName => {
|
||||
onUpdate({
|
||||
name: newName,
|
||||
});
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useMemo, useRef,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import isEmail from 'validator/lib/isEmail';
|
||||
import {
|
||||
Form, Grid, Header, Message,
|
||||
} from 'semantic-ui-react';
|
||||
import { Form, Grid, Header, Message } from 'semantic-ui-react';
|
||||
import { useDidUpdate, usePrevious, useToggle } from '../../lib/hooks';
|
||||
import { Input } from '../../lib/custom-ui';
|
||||
|
||||
|
@ -15,7 +11,7 @@ import { useForm } from '../../hooks';
|
|||
|
||||
import styles from './Login.module.css';
|
||||
|
||||
const createMessage = (error) => {
|
||||
const createMessage = error => {
|
||||
if (!error) {
|
||||
return error;
|
||||
}
|
||||
|
@ -50,9 +46,7 @@ const createMessage = (error) => {
|
|||
};
|
||||
|
||||
const Login = React.memo(
|
||||
({
|
||||
defaultData, isSubmitting, error, onAuthenticate, onMessageDismiss,
|
||||
}) => {
|
||||
({ defaultData, isSubmitting, error, onAuthenticate, onMessageDismiss }) => {
|
||||
const [t] = useTranslation();
|
||||
const wasSubmitting = usePrevious(isSubmitting);
|
||||
|
||||
|
@ -99,7 +93,7 @@ const Login = React.memo(
|
|||
|
||||
break;
|
||||
case 'Password is not valid':
|
||||
setData((prevData) => ({
|
||||
setData(prevData => ({
|
||||
...prevData,
|
||||
password: '',
|
||||
}));
|
||||
|
|
|
@ -8,13 +8,11 @@ import UserItem from './UserItem';
|
|||
|
||||
import styles from './AddMembershipPopup.module.css';
|
||||
|
||||
const AddMembershipStep = React.memo(({
|
||||
users, currentUserIds, onCreate, onClose,
|
||||
}) => {
|
||||
const AddMembershipStep = React.memo(({ users, currentUserIds, onCreate, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleUserSelect = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onCreate({
|
||||
userId: id,
|
||||
});
|
||||
|
@ -33,7 +31,7 @@ const AddMembershipStep = React.memo(({
|
|||
</Popup.Header>
|
||||
<Popup.Content>
|
||||
<div className={styles.menu}>
|
||||
{users.map((user) => (
|
||||
{users.map(user => (
|
||||
<UserItem
|
||||
key={user.id}
|
||||
name={user.name}
|
||||
|
|
|
@ -6,9 +6,7 @@ import User from '../../User';
|
|||
|
||||
import styles from './UserItem.module.css';
|
||||
|
||||
const UserItem = React.memo(({
|
||||
name, avatar, isActive, onSelect,
|
||||
}) => (
|
||||
const UserItem = React.memo(({ name, avatar, isActive, onSelect }) => (
|
||||
<button
|
||||
type="button"
|
||||
disabled={isActive}
|
||||
|
|
|
@ -15,9 +15,7 @@ const StepTypes = {
|
|||
DELETE: 'DELETE',
|
||||
};
|
||||
|
||||
const EditStep = React.memo(({
|
||||
defaultData, onUpdate, onDelete, onClose,
|
||||
}) => {
|
||||
const EditStep = React.memo(({ defaultData, onUpdate, onDelete, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [data, handleFieldChange] = useForm(() => ({
|
||||
|
|
|
@ -22,7 +22,7 @@ const Project = React.memo(
|
|||
onMembershipDelete,
|
||||
}) => {
|
||||
const handleMembershipDelete = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onMembershipDelete(id);
|
||||
},
|
||||
[onMembershipDelete],
|
||||
|
@ -47,7 +47,7 @@ const Project = React.memo(
|
|||
<span className={styles.name}>{name}</span>
|
||||
)}
|
||||
<span className={styles.users}>
|
||||
{memberships.map((membership) => (
|
||||
{memberships.map(membership => (
|
||||
<span key={membership.id} className={styles.user}>
|
||||
<EditMembershipPopup
|
||||
user={membership.user}
|
||||
|
@ -67,7 +67,7 @@ const Project = React.memo(
|
|||
{isEditable && (
|
||||
<AddMembershipPopup
|
||||
users={allUsers}
|
||||
currentUserIds={memberships.map((membership) => membership.user.id)}
|
||||
currentUserIds={memberships.map(membership => membership.user.id)}
|
||||
onCreate={onMembershipCreate}
|
||||
>
|
||||
<Button icon="add user" className={styles.addUser} />
|
||||
|
|
|
@ -7,9 +7,7 @@ import User from '../User';
|
|||
|
||||
import styles from './Item.module.css';
|
||||
|
||||
const Item = React.memo(({
|
||||
isPersisted, isActive, user, onUserSelect, onUserDeselect,
|
||||
}) => {
|
||||
const Item = React.memo(({ isPersisted, isActive, user, onUserSelect, onUserDeselect }) => {
|
||||
const handleToggleClick = useCallback(() => {
|
||||
if (isActive) {
|
||||
onUserDeselect();
|
||||
|
|
|
@ -9,20 +9,18 @@ import Item from './Item';
|
|||
import styles from './ProjectMembershipsStep.module.css';
|
||||
|
||||
const ProjectMembershipsStep = React.memo(
|
||||
({
|
||||
items, currentUserIds, title, onUserSelect, onUserDeselect, onBack,
|
||||
}) => {
|
||||
({ items, currentUserIds, title, onUserSelect, onUserDeselect, onBack }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleUserSelect = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onUserSelect(id);
|
||||
},
|
||||
[onUserSelect],
|
||||
);
|
||||
|
||||
const handleUserDeselect = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onUserDeselect(id);
|
||||
},
|
||||
[onUserDeselect],
|
||||
|
@ -33,7 +31,7 @@ const ProjectMembershipsStep = React.memo(
|
|||
<Popup.Header onBack={onBack}>{t(title)}</Popup.Header>
|
||||
<Popup.Content>
|
||||
<Menu secondary vertical className={styles.menu}>
|
||||
{items.map((item) => (
|
||||
{items.map(item => (
|
||||
<Item
|
||||
key={item.id}
|
||||
isPersisted={item.isPersisted}
|
||||
|
|
|
@ -12,16 +12,14 @@ import { ReactComponent as PlusIcon } from '../../assets/images/plus-icon.svg';
|
|||
|
||||
import styles from './Projects.module.css';
|
||||
|
||||
const Projects = React.memo(({
|
||||
items, currentId, isEditable, onAdd,
|
||||
}) => {
|
||||
const Projects = React.memo(({ items, currentId, isEditable, onAdd }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
if (isUndefined(currentId)) {
|
||||
return (
|
||||
<Container className={styles.cardsWrapper}>
|
||||
<Grid className={styles.gridFix}>
|
||||
{items.map((item) => (
|
||||
{items.map(item => (
|
||||
<Grid.Column key={item.id} mobile={8} computer={4}>
|
||||
<Link
|
||||
to={
|
||||
|
|
|
@ -32,9 +32,7 @@ const STYLES = {
|
|||
},
|
||||
};
|
||||
|
||||
const Timer = React.memo(({
|
||||
startedAt, total, size, isDisabled, onClick,
|
||||
}) => {
|
||||
const Timer = React.memo(({ startedAt, total, size, isDisabled, onClick }) => {
|
||||
const prevStartedAt = usePrevious(startedAt);
|
||||
const forceUpdate = useForceUpdate();
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ const COLORS = [
|
|||
'#2c3e50', // Midnight blue
|
||||
];
|
||||
|
||||
const getColor = (name) => {
|
||||
const getColor = name => {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < name.length; i += 1) {
|
||||
sum += name.charCodeAt(i);
|
||||
|
@ -64,9 +64,7 @@ const getColor = (name) => {
|
|||
return COLORS[sum % COLORS.length];
|
||||
};
|
||||
|
||||
const User = React.memo(({
|
||||
name, avatar, size, isDisabled, onClick,
|
||||
}) => {
|
||||
const User = React.memo(({ name, avatar, size, isDisabled, onClick }) => {
|
||||
const style = {
|
||||
...STYLES[size],
|
||||
background: avatar ? `url("${avatar}")` : getColor(name),
|
||||
|
|
|
@ -9,9 +9,7 @@ import User from '../User';
|
|||
import styles from './EditAvatarStep.module.css';
|
||||
|
||||
const EditAvatarStep = React.memo(
|
||||
({
|
||||
defaultValue, name, isUploading, onUpload, onClear, onBack,
|
||||
}) => {
|
||||
({ defaultValue, name, isUploading, onUpload, onClear, onBack }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const field = useRef(null);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import isEmail from 'validator/lib/isEmail';
|
||||
import React, {
|
||||
useCallback, useEffect, useMemo, useRef,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Form, Message } from 'semantic-ui-react';
|
||||
|
@ -12,7 +10,7 @@ import { useForm } from '../../hooks';
|
|||
|
||||
import styles from './EditNameStep.module.css';
|
||||
|
||||
const createMessage = (error) => {
|
||||
const createMessage = error => {
|
||||
if (!error) {
|
||||
return error;
|
||||
}
|
||||
|
@ -37,9 +35,7 @@ const createMessage = (error) => {
|
|||
};
|
||||
|
||||
const EditEmailStep = React.memo(
|
||||
({
|
||||
defaultData, email, isSubmitting, error, onUpdate, onMessageDismiss, onBack, onClose,
|
||||
}) => {
|
||||
({ defaultData, email, isSubmitting, error, onUpdate, onMessageDismiss, onBack, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
const wasSubmitting = usePrevious(isSubmitting);
|
||||
|
||||
|
@ -92,7 +88,7 @@ const EditEmailStep = React.memo(
|
|||
|
||||
break;
|
||||
case 'Current password is not valid':
|
||||
setData((prevData) => ({
|
||||
setData(prevData => ({
|
||||
...prevData,
|
||||
currentPassword: '',
|
||||
}));
|
||||
|
|
|
@ -8,9 +8,7 @@ import { useField } from '../../hooks';
|
|||
|
||||
import styles from './EditNameStep.module.css';
|
||||
|
||||
const EditNameStep = React.memo(({
|
||||
defaultValue, onUpdate, onBack, onClose,
|
||||
}) => {
|
||||
const EditNameStep = React.memo(({ defaultValue, onUpdate, onBack, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
const [value, handleFieldChange] = useField(defaultValue);
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, {
|
||||
useCallback, useEffect, useMemo, useRef,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Form, Message } from 'semantic-ui-react';
|
||||
|
@ -11,7 +9,7 @@ import { useForm } from '../../hooks';
|
|||
|
||||
import styles from './EditNameStep.module.css';
|
||||
|
||||
const createMessage = (error) => {
|
||||
const createMessage = error => {
|
||||
if (!error) {
|
||||
return error;
|
||||
}
|
||||
|
@ -31,9 +29,7 @@ const createMessage = (error) => {
|
|||
};
|
||||
|
||||
const EditPasswordStep = React.memo(
|
||||
({
|
||||
defaultData, isSubmitting, error, onUpdate, onMessageDismiss, onBack, onClose,
|
||||
}) => {
|
||||
({ defaultData, isSubmitting, error, onUpdate, onMessageDismiss, onBack, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
const wasSubmitting = usePrevious(isSubmitting);
|
||||
|
||||
|
@ -72,7 +68,7 @@ const EditPasswordStep = React.memo(
|
|||
if (!error) {
|
||||
onClose();
|
||||
} else if (error.message === 'Current password is not valid') {
|
||||
setData((prevData) => ({
|
||||
setData(prevData => ({
|
||||
...prevData,
|
||||
currentPassword: '',
|
||||
}));
|
||||
|
|
|
@ -57,7 +57,7 @@ const UserStep = React.memo(
|
|||
}, [openStep]);
|
||||
|
||||
const handleNameUpdate = useCallback(
|
||||
(newName) => {
|
||||
newName => {
|
||||
onUpdate({
|
||||
name: newName,
|
||||
});
|
||||
|
|
|
@ -7,9 +7,7 @@ import DeletePopup from '../DeletePopup';
|
|||
|
||||
import styles from './Item.module.css';
|
||||
|
||||
const Item = React.memo(({
|
||||
name, email, isAdmin, onUpdate, onDelete,
|
||||
}) => {
|
||||
const Item = React.memo(({ name, email, isAdmin, onUpdate, onDelete }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleIsAdminChange = useCallback(() => {
|
||||
|
|
|
@ -6,9 +6,7 @@ import { Button, Modal, Table } from 'semantic-ui-react';
|
|||
import AddUserPopupContainer from '../../containers/AddUserPopupContainer';
|
||||
import Item from './Item';
|
||||
|
||||
const UsersModal = React.memo(({
|
||||
items, onUpdate, onDelete, onClose,
|
||||
}) => {
|
||||
const UsersModal = React.memo(({ items, onUpdate, onDelete, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleUpdate = useCallback(
|
||||
|
@ -19,7 +17,7 @@ const UsersModal = React.memo(({
|
|||
);
|
||||
|
||||
const handleDelete = useCallback(
|
||||
(id) => {
|
||||
id => {
|
||||
onDelete(id);
|
||||
},
|
||||
[onDelete],
|
||||
|
@ -43,13 +41,13 @@ const UsersModal = React.memo(({
|
|||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{items.map((item) => (
|
||||
{items.map(item => (
|
||||
<Item
|
||||
key={item.id}
|
||||
name={item.name}
|
||||
email={item.email}
|
||||
isAdmin={item.isAdmin}
|
||||
onUpdate={(data) => handleUpdate(item.id, data)}
|
||||
onUpdate={data => handleUpdate(item.id, data)}
|
||||
onDelete={() => handleDelete(item.id)}
|
||||
/>
|
||||
))}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue