diff --git a/Dockerfile b/Dockerfile index 23598ac6..5b673b70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,8 @@ COPY --from=client-builder /app/build/index.html views ENV BASE_URL DATABASE_URL -VOLUME /app/public/uploads +VOLUME /app/public/user-avatars +VOLUME /app/public/attachments EXPOSE 1337 diff --git a/README.md b/README.md index d7e98ed9..c7aaf8e3 100644 --- a/README.md +++ b/README.md @@ -82,11 +82,11 @@ Demo user: demo@demo.demo demo ## Roadmap +- [x] File attachments +- [ ] Member permissions - [ ] Fetch last data after reconnection -- [ ] File attachments - [ ] Custom fields - [ ] Public boards -- [ ] Member permissions - [ ] Automatic actions ## License diff --git a/client/src/actions/attachment.js b/client/src/actions/attachment.js new file mode 100644 index 00000000..e81bb9ed --- /dev/null +++ b/client/src/actions/attachment.js @@ -0,0 +1,117 @@ +import ActionTypes from '../constants/ActionTypes'; + +/* Actions */ + +export const createAttachment = (attachment) => ({ + type: ActionTypes.ATTACHMENT_CREATE, + payload: { + attachment, + }, +}); + +export const updateAttachment = (id, data) => ({ + type: ActionTypes.ATTACHMENT_UPDATE, + payload: { + id, + data, + }, +}); + +export const deleteAttachment = (id) => ({ + type: ActionTypes.ATTACHMENT_DELETE, + payload: { + id, + }, +}); + +/* Events */ + +export const createAttachmentRequested = (localId, data) => ({ + type: ActionTypes.ATTACHMENT_CREATE_REQUESTED, + payload: { + localId, + data, + }, +}); + +export const createAttachmentSucceeded = (localId, attachment) => ({ + type: ActionTypes.ATTACHMENT_CREATE_SUCCEEDED, + payload: { + localId, + attachment, + }, +}); + +export const createAttachmentFailed = (localId, error) => ({ + type: ActionTypes.ATTACHMENT_CREATE_FAILED, + payload: { + localId, + error, + }, +}); + +export const createAttachmentReceived = (attachment) => ({ + type: ActionTypes.ATTACHMENT_CREATE_RECEIVED, + payload: { + attachment, + }, +}); + +export const updateAttachmentRequested = (id, data) => ({ + type: ActionTypes.ATTACHMENT_UPDATE_REQUESTED, + payload: { + id, + data, + }, +}); + +export const updateAttachmentSucceeded = (attachment) => ({ + type: ActionTypes.ATTACHMENT_UPDATE_SUCCEEDED, + payload: { + attachment, + }, +}); + +export const updateAttachmentFailed = (id, error) => ({ + type: ActionTypes.ATTACHMENT_UPDATE_FAILED, + payload: { + id, + error, + }, +}); + +export const updateAttachmentReceived = (attachment) => ({ + type: ActionTypes.ATTACHMENT_UPDATE_RECEIVED, + payload: { + attachment, + }, +}); + +export const deleteAttachmentRequested = (id) => ({ + type: ActionTypes.ATTACHMENT_DELETE_REQUESTED, + payload: { + id, + }, +}); + +export const deleteAttachmentSucceeded = (attachment) => ({ + type: ActionTypes.ATTACHMENT_DELETE_SUCCEEDED, + payload: { + attachment, + }, +}); + +export const deleteAttachmentFailed = (id, error) => ({ + type: ActionTypes.ATTACHMENT_DELETE_FAILED, + payload: { + id, + error, + }, +}); + +export const deleteAttachmentReceived = (attachment) => ({ + type: ActionTypes.ATTACHMENT_DELETE_RECEIVED, + payload: { + attachment, + }, +}); diff --git a/client/src/actions/board.js b/client/src/actions/board.js index ff842c17..0f91ac43 100644 --- a/client/src/actions/board.js +++ b/client/src/actions/board.js @@ -76,6 +76,7 @@ export const fetchBoardSucceeded = ( cardMemberships, cardLabels, tasks, + attachments, ) => ({ type: ActionTypes.BOARD_FETCH_SUCCEEDED, payload: { @@ -86,6 +87,7 @@ export const fetchBoardSucceeded = ( cardMemberships, cardLabels, tasks, + attachments, }, }); diff --git a/client/src/actions/entry/attachment.js b/client/src/actions/entry/attachment.js new file mode 100644 index 00000000..8940f5ab --- /dev/null +++ b/client/src/actions/entry/attachment.js @@ -0,0 +1,23 @@ +import EntryActionTypes from '../../constants/EntryActionTypes'; + +export const createAttachmentInCurrentCard = (data) => ({ + type: EntryActionTypes.ATTACHMENT_IN_CURRENT_CARD_CREATE, + payload: { + data, + }, +}); + +export const updateAttachment = (id, data) => ({ + type: EntryActionTypes.ATTACHMENT_UPDATE, + payload: { + id, + data, + }, +}); + +export const deleteAttachment = (id) => ({ + type: EntryActionTypes.ATTACHMENT_DELETE, + payload: { + id, + }, +}); diff --git a/client/src/actions/entry/index.js b/client/src/actions/entry/index.js index 5332dbe6..a6c6498b 100755 --- a/client/src/actions/entry/index.js +++ b/client/src/actions/entry/index.js @@ -8,6 +8,7 @@ export * from './list'; export * from './label'; export * from './card'; export * from './task'; +export * from './attachment'; export * from './actions'; export * from './comment-action'; export * from './notification'; diff --git a/client/src/actions/entry/user.js b/client/src/actions/entry/user.js index 32cf63cd..7abf8013 100755 --- a/client/src/actions/entry/user.js +++ b/client/src/actions/entry/user.js @@ -63,10 +63,10 @@ export const clearCurrentUserUsernameUpdateError = () => ({ payload: {}, }); -export const uploadCurrentUserAvatar = (file) => ({ - type: EntryActionTypes.CURRENT_USER_AVATAR_UPLOAD, +export const updateCurrentUserAvatar = (data) => ({ + type: EntryActionTypes.CURRENT_USER_AVATAR_UPDATE, payload: { - file, + data, }, }); diff --git a/client/src/actions/index.js b/client/src/actions/index.js index f5b78971..de0e79b9 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.js @@ -14,6 +14,7 @@ export * from './card'; export * from './card-membership'; export * from './card-label'; export * from './task'; +export * from './attachment'; export * from './actions'; export * from './action'; export * from './comment-action'; diff --git a/client/src/actions/user.js b/client/src/actions/user.js index 5464795c..1ae875fd 100644 --- a/client/src/actions/user.js +++ b/client/src/actions/user.js @@ -233,23 +233,23 @@ export const updateUserUsernameFailed = (id, error) => ({ }, }); -export const uploadUserAvatarRequested = (id) => ({ - type: ActionTypes.USER_AVATAR_UPLOAD_REQUESTED, +export const updateUserAvatarRequested = (id) => ({ + type: ActionTypes.USER_AVATAR_UPDATE_REQUESTED, payload: { id, }, }); -export const uploadUserAvatarSucceeded = (id, avatar) => ({ - type: ActionTypes.USER_AVATAR_UPLOAD_SUCCEEDED, +export const updateUserAvatarSucceeded = (id, avatarUrl) => ({ + type: ActionTypes.USER_AVATAR_UPDATE_SUCCEEDED, payload: { id, - avatar, + avatarUrl, }, }); -export const uploadUserAvatarFailed = (id, error) => ({ - type: ActionTypes.USER_AVATAR_UPLOAD_FAILED, +export const updateUserAvatarFailed = (id, error) => ({ + type: ActionTypes.USER_AVATAR_UPDATE_FAILED, payload: { id, error, diff --git a/client/src/api/attachments.js b/client/src/api/attachments.js new file mode 100755 index 00000000..7b5fc25c --- /dev/null +++ b/client/src/api/attachments.js @@ -0,0 +1,51 @@ +import http from './http'; +import socket from './socket'; + +/* Transformers */ + +export const transformAttachment = (attachment) => ({ + ...attachment, + createdAt: new Date(attachment.createdAt), +}); + +/* Actions */ + +const createAttachment = (cardId, data, headers) => + http.post(`/cards/${cardId}/attachments`, data, headers).then((body) => ({ + ...body, + item: transformAttachment(body.item), + })); + +const updateAttachment = (id, data, headers) => + socket.patch(`/attachments/${id}`, data, headers).then((body) => ({ + ...body, + item: transformAttachment(body.item), + })); + +const deleteAttachment = (id, headers) => + socket.delete(`/attachments/${id}`, undefined, headers).then((body) => ({ + ...body, + item: transformAttachment(body.item), + })); + +/* Event handlers */ + +const makeHandleAttachmentCreate = (next) => (body) => { + next({ + ...body, + item: transformAttachment(body.item), + }); +}; + +const makeHandleAttachmentUpdate = makeHandleAttachmentCreate; + +const makeHandleAttachmentDelete = makeHandleAttachmentCreate; + +export default { + createAttachment, + updateAttachment, + deleteAttachment, + makeHandleAttachmentCreate, + makeHandleAttachmentUpdate, + makeHandleAttachmentDelete, +}; diff --git a/client/src/api/boards.js b/client/src/api/boards.js index 68b609bb..b605ed2e 100755 --- a/client/src/api/boards.js +++ b/client/src/api/boards.js @@ -1,5 +1,6 @@ import socket from './socket'; import { transformCard } from './cards'; +import { transformAttachment } from './attachments'; /* Actions */ @@ -12,6 +13,7 @@ const getBoard = (id, headers) => included: { ...body.included, cards: body.included.cards.map(transformCard), + attachments: body.included.attachments.map(transformAttachment), }, })); diff --git a/client/src/api/index.js b/client/src/api/index.js index 236738b4..245a1dd8 100755 --- a/client/src/api/index.js +++ b/client/src/api/index.js @@ -11,6 +11,7 @@ import cards from './cards'; import cardMemberships from './card-memberships'; import cardLabels from './card-labels'; import tasks from './tasks'; +import attachments from './attachments'; import actions from './actions'; import commentActions from './comment-actions'; import notifications from './notifications'; @@ -29,6 +30,7 @@ export default { ...cardMemberships, ...cardLabels, ...tasks, + ...attachments, ...actions, ...commentActions, ...notifications, diff --git a/client/src/api/users.js b/client/src/api/users.js index 2c28c976..272ce30f 100755 --- a/client/src/api/users.js +++ b/client/src/api/users.js @@ -19,14 +19,8 @@ const updateUserPassword = (id, data, headers) => const updateUserUsername = (id, data, headers) => socket.patch(`/users/${id}/username`, data, headers); -const uploadUserAvatar = (id, file, headers) => - http.post( - `/users/${id}/upload-avatar`, - { - file, - }, - headers, - ); +const updateUserAvatar = (id, data, headers) => + http.post(`/users/${id}/update-avatar`, data, headers); const deleteUser = (id, headers) => socket.delete(`/users/${id}`, undefined, headers); @@ -38,6 +32,6 @@ export default { updateUserEmail, updateUserPassword, updateUserUsername, - uploadUserAvatar, + updateUserAvatar, deleteUser, }; diff --git a/client/src/components/Board/Filter.jsx b/client/src/components/Board/Filter.jsx index f2597f07..0e3ec547 100644 --- a/client/src/components/Board/Filter.jsx +++ b/client/src/components/Board/Filter.jsx @@ -60,7 +60,7 @@ const Filter = React.memo( handleUserRemoveClick(user.id)} /> diff --git a/client/src/components/Card/Card.jsx b/client/src/components/Card/Card.jsx index 6424c3ac..ee1f438c 100755 --- a/client/src/components/Card/Card.jsx +++ b/client/src/components/Card/Card.jsx @@ -103,7 +103,7 @@ const Card = React.memo( {users.map((user) => ( - + ))} diff --git a/client/src/components/Card/Card.module.css b/client/src/components/Card/Card.module.css index ea9f7e86..42a03fb0 100644 --- a/client/src/components/Card/Card.module.css +++ b/client/src/components/Card/Card.module.css @@ -58,7 +58,7 @@ .card:hover { background-color: #f5f6f7; - border-bottom-color: rgba(9, 45, 66, 0.25); + border-bottom-color: rgba(9, 30, 66, 0.25); } .card:hover .target { diff --git a/client/src/components/CardModal/Actions/EditComment.module.css b/client/src/components/CardModal/Actions/EditComment.module.css index 9c3e9b6b..9e40d746 100644 --- a/client/src/components/CardModal/Actions/EditComment.module.css +++ b/client/src/components/CardModal/Actions/EditComment.module.css @@ -5,7 +5,7 @@ .field { background: #fff !important; - border: 1px solid rgba(9, 45, 66, 0.13) !important; + border: 1px solid rgba(9, 30, 66, 0.13) !important; border-radius: 3px !important; box-sizing: border-box; color: #333 !important; diff --git a/client/src/components/CardModal/Actions/Item.jsx b/client/src/components/CardModal/Actions/Item.jsx index f1d36934..6433e50d 100755 --- a/client/src/components/CardModal/Actions/Item.jsx +++ b/client/src/components/CardModal/Actions/Item.jsx @@ -62,7 +62,7 @@ const Item = React.memo(({ type, data, createdAt, user }) => { return ( - +
{contentNode}
diff --git a/client/src/components/CardModal/Actions/ItemComment.jsx b/client/src/components/CardModal/Actions/ItemComment.jsx index 931c95e9..865caa5f 100755 --- a/client/src/components/CardModal/Actions/ItemComment.jsx +++ b/client/src/components/CardModal/Actions/ItemComment.jsx @@ -24,7 +24,7 @@ const ItemComment = React.memo( return ( - +
diff --git a/client/src/components/CardModal/Actions/ItemComment.module.css b/client/src/components/CardModal/Actions/ItemComment.module.css index b9c8a075..e2ec035d 100644 --- a/client/src/components/CardModal/Actions/ItemComment.module.css +++ b/client/src/components/CardModal/Actions/ItemComment.module.css @@ -24,8 +24,8 @@ .text { background-color: #fff; border-radius: 0px 8px 8px; - box-shadow: 0 1px 2px -1px rgba(9, 45, 66, 0.25), - 0 0 0 1px rgba(9, 45, 66, 0.08); + box-shadow: 0 1px 2px -1px rgba(9, 30, 66, 0.25), + 0 0 0 1px rgba(9, 30, 66, 0.08); box-sizing: border-box; color: #17394d; display: inline-block; diff --git a/client/src/components/CardModal/Attachments/Attachments.jsx b/client/src/components/CardModal/Attachments/Attachments.jsx new file mode 100644 index 00000000..e3d1e656 --- /dev/null +++ b/client/src/components/CardModal/Attachments/Attachments.jsx @@ -0,0 +1,45 @@ +import React, { useCallback } from 'react'; +import PropTypes from 'prop-types'; + +import Item from './Item'; + +const Attachments = React.memo(({ items, onUpdate, onDelete }) => { + const handleUpdate = useCallback( + (id, data) => { + onUpdate(id, data); + }, + [onUpdate], + ); + + const handleDelete = useCallback( + (id) => { + onDelete(id); + }, + [onDelete], + ); + + return ( + <> + {items.map((item) => ( + handleUpdate(item.id, data)} + onDelete={() => handleDelete(item.id)} + /> + ))} + + ); +}); + +Attachments.propTypes = { + items: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types + onUpdate: PropTypes.func.isRequired, + onDelete: PropTypes.func.isRequired, +}; + +export default Attachments; diff --git a/client/src/components/CardModal/Attachments/EditPopup.jsx b/client/src/components/CardModal/Attachments/EditPopup.jsx new file mode 100755 index 00000000..7a29d7a9 --- /dev/null +++ b/client/src/components/CardModal/Attachments/EditPopup.jsx @@ -0,0 +1,107 @@ +import dequal from 'dequal'; +import React, { useCallback, useEffect, useRef } from 'react'; +import PropTypes from 'prop-types'; +import { useTranslation } from 'react-i18next'; +import { Button, Form } from 'semantic-ui-react'; +import { withPopup } from '../../../lib/popup'; +import { Input, Popup } from '../../../lib/custom-ui'; + +import { useForm, useSteps } from '../../../hooks'; +import DeleteStep from '../../DeleteStep'; + +import styles from './EditPopup.module.css'; + +const StepTypes = { + DELETE: 'DELETE', +}; + +const EditStep = React.memo(({ defaultData, onUpdate, onDelete, onClose }) => { + const [t] = useTranslation(); + + const [data, handleFieldChange] = useForm(() => ({ + name: '', + ...defaultData, + })); + + const [step, openStep, handleBack] = useSteps(); + + const nameField = useRef(null); + + const handleSubmit = useCallback(() => { + const cleanData = { + ...data, + name: data.name.trim(), + }; + + if (!cleanData.name) { + nameField.current.select(); + return; + } + + if (!dequal(cleanData, defaultData)) { + onUpdate(cleanData); + } + + onClose(); + }, [defaultData, onUpdate, onClose, data]); + + const handleDeleteClick = useCallback(() => { + openStep(StepTypes.DELETE); + }, [openStep]); + + useEffect(() => { + nameField.current.select(); + }, []); + + if (step && step.type === StepTypes.DELETE) { + return ( + + ); + } + + return ( + <> + + {t('common.editAttachment', { + context: 'title', + })} + + +
+
{t('common.title')}
+ +
+ +
+ ); + }, +); + +Item.propTypes = { + name: PropTypes.string.isRequired, + url: PropTypes.string, + thumbnailUrl: PropTypes.string, + createdAt: PropTypes.instanceOf(Date), + isPersisted: PropTypes.bool.isRequired, + onUpdate: PropTypes.func.isRequired, + onDelete: PropTypes.func.isRequired, +}; + +Item.defaultProps = { + url: undefined, + thumbnailUrl: undefined, + createdAt: undefined, +}; + +export default Item; diff --git a/client/src/components/CardModal/Attachments/Item.module.css b/client/src/components/CardModal/Attachments/Item.module.css new file mode 100644 index 00000000..c0323146 --- /dev/null +++ b/client/src/components/CardModal/Attachments/Item.module.css @@ -0,0 +1,90 @@ +.button { + background: transparent !important; + box-shadow: none !important; + line-height: 28px !important; + margin: 0 !important; + min-height: auto !important; + opacity: 0; + padding: 0 !important; + position: absolute; + right: 2px; + top: 2px; + width: 28px; +} + +.button:hover { + background-color: rgba(9, 30, 66, 0.08) !important; +} + +.details { + box-sizing: border-box; + padding: 8px 32px 8px 128px; + margin: 0; + min-height: 80px; + z-index: 0; +} + +.extension { + color: #5e6c84; + display: block; + font-size: 18px; + font-weight: 700; + height: 100%; + line-height: 80px; + text-align: center; + text-decoration: none; + text-transform: uppercase; + width: 100%; +} + +.name { + color: #17394d; + font-size: 14px; + font-weight: 700; + line-height: 20px; + word-wrap: break-word; +} + +.options { + display: block; + color: #6b808c; + line-height: 20px; + margin-bottom: 8px; +} + +.thumbnail { + border-radius: 3px; + background-color: rgba(9, 30, 66, 0.04); + background-position: center; + background-repeat: no-repeat; + background-size: cover; + border-radius: 3px; + height: 80px; + left: 0; + margin-top: -40px; + position: absolute; + text-align: center; + text-decoration: none; + top: 50%; + width: 112px; + z-index: 1; +} + +.wrapper { + cursor: pointer; + margin-bottom: 8px; + min-height: 80px; + position: relative; +} + +.wrapper:hover .details { + background-color: rgba(9, 30, 66, 0.04); +} + +.wrapper:hover .target { + opacity: 1; +} + +.wrapperSubmitting { + background-color: rgba(9, 30, 66, 0.04); +} diff --git a/client/src/components/CardModal/Attachments/index.js b/client/src/components/CardModal/Attachments/index.js new file mode 100644 index 00000000..b1032429 --- /dev/null +++ b/client/src/components/CardModal/Attachments/index.js @@ -0,0 +1,3 @@ +import Attachments from './Attachments'; + +export default Attachments; diff --git a/client/src/components/CardModal/CardModal.jsx b/client/src/components/CardModal/CardModal.jsx index 92dcecc4..c56496ed 100755 --- a/client/src/components/CardModal/CardModal.jsx +++ b/client/src/components/CardModal/CardModal.jsx @@ -3,11 +3,12 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import { Button, Grid, Icon, Modal } from 'semantic-ui-react'; -import { Markdown } from '../../lib/custom-ui'; +import { FilePicker, Markdown } from '../../lib/custom-ui'; import NameField from './NameField'; import EditDescription from './EditDescription'; import Tasks from './Tasks'; +import Attachments from './Attachments'; import Actions from './Actions'; import User from '../User'; import Label from '../Label'; @@ -33,6 +34,7 @@ const CardModal = React.memo( users, labels, tasks, + attachments, actions, allProjectMemberships, allLabels, @@ -49,6 +51,9 @@ const CardModal = React.memo( onTaskCreate, onTaskUpdate, onTaskDelete, + onAttachmentCreate, + onAttachmentUpdate, + onAttachmentDelete, onActionsFetch, onCommentActionCreate, onCommentActionUpdate, @@ -93,6 +98,15 @@ const CardModal = React.memo( [onUpdate], ); + const handleAttachmentFileSelect = useCallback( + (file) => { + onAttachmentCreate({ + file, + }); + }, + [onAttachmentCreate], + ); + const handleToggleSubscribeClick = useCallback(() => { onUpdate({ isSubscribed: !isSubscribed, @@ -134,7 +148,7 @@ const CardModal = React.memo( onUserSelect={onUserAdd} onUserDeselect={onUserRemove} > - + ))} @@ -255,6 +269,19 @@ const CardModal = React.memo( />
+ {attachments.length > 0 && ( +
+
+ +
{t('common.attachments')}
+ +
+
+ )} + + +
{t('common.actions')} @@ -347,6 +380,7 @@ CardModal.propTypes = { users: PropTypes.array.isRequired, labels: PropTypes.array.isRequired, tasks: PropTypes.array.isRequired, + attachments: PropTypes.array.isRequired, actions: PropTypes.array.isRequired, allProjectMemberships: PropTypes.array.isRequired, allLabels: PropTypes.array.isRequired, @@ -364,6 +398,9 @@ CardModal.propTypes = { onTaskCreate: PropTypes.func.isRequired, onTaskUpdate: PropTypes.func.isRequired, onTaskDelete: PropTypes.func.isRequired, + onAttachmentCreate: PropTypes.func.isRequired, + onAttachmentUpdate: PropTypes.func.isRequired, + onAttachmentDelete: PropTypes.func.isRequired, onActionsFetch: PropTypes.func.isRequired, onCommentActionCreate: PropTypes.func.isRequired, onCommentActionUpdate: PropTypes.func.isRequired, diff --git a/client/src/components/CardModal/CardModal.module.css b/client/src/components/CardModal/CardModal.module.css index 60abe4fc..0d5ec88b 100644 --- a/client/src/components/CardModal/CardModal.module.css +++ b/client/src/components/CardModal/CardModal.module.css @@ -1,6 +1,6 @@ .actionButton { background: #ebeef0 !important; - box-shadow: 0 1px 0 0 rgba(9, 45, 66, 0.13) !important; + box-shadow: 0 1px 0 0 rgba(9, 30, 66, 0.13) !important; color: #444 !important; margin-top: 8px !important; overflow: hidden; @@ -12,7 +12,7 @@ .actionButton:hover { background: #dfe3e6 !important; - box-shadow: 0 1px 0 0 rgba(9, 45, 66, 0.25) !important; + box-shadow: 0 1px 0 0 rgba(9, 30, 66, 0.25) !important; color: #4c4c4c !important; } @@ -65,7 +65,7 @@ } .dueDate { - background: #dce0e4; + background: rgba(9, 30, 66, 0.04); border: none; border-radius: 3px; color: #6b808c; @@ -79,12 +79,12 @@ } .dueDate:hover { - background: #d2d8dc; + background: rgba(9, 30, 66, 0.08); color: #17394d; } .descriptionButton { - background: rgba(9, 45, 66, 0.08); + background: rgba(9, 30, 66, 0.04); border: none; border-radius: 3px; display: block; @@ -100,7 +100,7 @@ } .descriptionButton:hover { - background-color: rgba(9, 45, 66, 0.13); + background-color: rgba(9, 30, 66, 0.08); color: #092d42; } diff --git a/client/src/components/CardModal/EditDescription.module.css b/client/src/components/CardModal/EditDescription.module.css index a17515b9..1c7ae1c0 100644 --- a/client/src/components/CardModal/EditDescription.module.css +++ b/client/src/components/CardModal/EditDescription.module.css @@ -5,7 +5,7 @@ .field { background: #fff !important; - border: 1px solid rgba(9, 45, 66, 0.13) !important; + border: 1px solid rgba(9, 30, 66, 0.13) !important; border-radius: 3px !important; color: #17394d !important; display: block !important; diff --git a/client/src/components/CardModal/Tasks/Add.module.css b/client/src/components/CardModal/Tasks/Add.module.css index c18cf2e5..65bac9da 100644 --- a/client/src/components/CardModal/Tasks/Add.module.css +++ b/client/src/components/CardModal/Tasks/Add.module.css @@ -5,7 +5,7 @@ .field { background: #fff !important; - border: 1px solid rgba(9, 45, 66, 0.13) !important; + border: 1px solid rgba(9, 30, 66, 0.08) !important; border-radius: 3px !important; color: #17394d !important; display: block !important; diff --git a/client/src/components/CardModal/Tasks/EditName.module.css b/client/src/components/CardModal/Tasks/EditName.module.css index 406bade3..f775e271 100644 --- a/client/src/components/CardModal/Tasks/EditName.module.css +++ b/client/src/components/CardModal/Tasks/EditName.module.css @@ -5,7 +5,7 @@ .field { background: #fff !important; - border: 1px solid rgba(9, 45, 66, 0.13) !important; + border: 1px solid rgba(9, 30, 66, 0.13) !important; border-radius: 3px !important; box-sizing: border-box !important; color: #17394d !important; diff --git a/client/src/components/CardModal/Tasks/Item.module.css b/client/src/components/CardModal/Tasks/Item.module.css index 079c5978..87aa13fc 100644 --- a/client/src/components/CardModal/Tasks/Item.module.css +++ b/client/src/components/CardModal/Tasks/Item.module.css @@ -13,7 +13,7 @@ } .button:hover { - background-color: rgba(9, 45, 66, 0.13) !important; + background-color: rgba(9, 30, 66, 0.08) !important; } .checkboxWrapper { @@ -30,7 +30,7 @@ } .content:hover { - background-color: rgba(9, 45, 66, 0.08); + background-color: rgba(9, 30, 66, 0.04); } .content:hover .target { diff --git a/client/src/components/CardModal/Tasks/Tasks.module.css b/client/src/components/CardModal/Tasks/Tasks.module.css index dcb9e120..0d71f82b 100644 --- a/client/src/components/CardModal/Tasks/Tasks.module.css +++ b/client/src/components/CardModal/Tasks/Tasks.module.css @@ -20,7 +20,7 @@ } .taskButton:hover { - background-color: rgba(9, 45, 66, 0.13); + background-color: rgba(9, 30, 66, 0.04); color: #092d42; } diff --git a/client/src/components/Header/NotificationsPopup.jsx b/client/src/components/Header/NotificationsPopup.jsx index b992ba0c..24d9334b 100755 --- a/client/src/components/Header/NotificationsPopup.jsx +++ b/client/src/components/Header/NotificationsPopup.jsx @@ -83,7 +83,7 @@ const NotificationsStep = React.memo(({ items, onDelete, onClose }) => { <> {renderItemContent(item)} diff --git a/client/src/components/List/List.module.css b/client/src/components/List/List.module.css index 67aae821..8d236be6 100644 --- a/client/src/components/List/List.module.css +++ b/client/src/components/List/List.module.css @@ -72,7 +72,7 @@ } .headerButton:hover { - background-color: rgba(9, 45, 66, 0.13) !important; + background-color: rgba(9, 30, 66, 0.13) !important; color: #516b7a !important; } diff --git a/client/src/components/Project/AddMembershipPopup/AddMembershipPopup.jsx b/client/src/components/Project/AddMembershipPopup/AddMembershipPopup.jsx index 36e62940..5544f2fa 100755 --- a/client/src/components/Project/AddMembershipPopup/AddMembershipPopup.jsx +++ b/client/src/components/Project/AddMembershipPopup/AddMembershipPopup.jsx @@ -35,7 +35,7 @@ const AddMembershipStep = React.memo(({ users, currentUserIds, onCreate, onClose handleUserSelect(user.id)} /> diff --git a/client/src/components/Project/AddMembershipPopup/UserItem.jsx b/client/src/components/Project/AddMembershipPopup/UserItem.jsx index d16b1626..b88aa021 100644 --- a/client/src/components/Project/AddMembershipPopup/UserItem.jsx +++ b/client/src/components/Project/AddMembershipPopup/UserItem.jsx @@ -6,7 +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, avatarUrl, isActive, onSelect }) => (
{defaultValue && (