Skip to content

Commit

Permalink
Merge pull request #339 from connect-foundation/master
Browse files Browse the repository at this point in the history
release 0.1.2
  • Loading branch information
sjh2428 authored Dec 6, 2019
2 parents 0122cbe + f53358d commit 521e971
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 86 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,16 @@ MDA(Mail Delivery Agent): POP3, IMTP를 통해 서버에 저장된 이메일을

### 메일 리스트

![메일](https://user-images.githubusercontent.com/31912670/69363194-60ce7f80-0cd3-11ea-9d89-19d1bde39eb1.png)
![메일리스트](https://user-images.githubusercontent.com/33617083/70243807-a781a680-17b6-11ea-8035-fcd66c8f4b7c.PNG)

### 메일쓰기

![메일쓰기](https://user-images.githubusercontent.com/31912670/69363193-6035e900-0cd3-11ea-939b-95823be1ba9a.png)
![메일쓰기](https://user-images.githubusercontent.com/33617083/70243577-304c1280-17b6-11ea-9a0f-73207ebff50f.PNG)

### 메일읽기

![메일읽기](https://user-images.githubusercontent.com/33617083/69391164-44533700-0d15-11ea-96c3-1a1dc3a3b83c.PNG)
![메일읽기](https://user-images.githubusercontent.com/33617083/70243581-30e4a900-17b6-11ea-9c23-d0461c65598e.PNG)


## Prerequisites

Expand Down
12 changes: 9 additions & 3 deletions server/src/libraries/save-to-infra.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import Imap from 'imap';
import ErrorField from './exception/error-field';
import ErrorResponse from './exception/error-response';
import ERROR_CODE from './exception/error-code';

const { DEFAULT_DOMAIN_NAME, IMAP_PORT } = process.env;
const PREFIX = '';
Expand Down Expand Up @@ -38,7 +41,8 @@ export const addMailBox = ({ user, name }) => {
connectImap(user, imap => {
imap.addBox(PREFIX + name, err => {
if (err) {
throw err;
const errorField = new ErrorField('mailBox', name, '존재하지 않는 메일함입니다');
throw new ErrorResponse(ERROR_CODE.MAILBOX_NOT_FOUND, errorField);
}
});
});
Expand All @@ -48,7 +52,8 @@ export const renameMailBox = ({ user, oldName, newName }) => {
connectImap(user, imap => {
imap.renameBox(PREFIX + oldName, PREFIX + newName, err => {
if (err) {
throw err;
const errorField = new ErrorField('mailBox', oldName, '존재하지 않는 메일함입니다');
throw new ErrorResponse(ERROR_CODE.MAILBOX_NOT_FOUND, errorField);
}
});
});
Expand All @@ -58,7 +63,8 @@ export const deleteMailBox = ({ user, name }) => {
connectImap(user, imap => {
imap.delBox(PREFIX + name, err => {
if (err) {
throw err;
const errorField = new ErrorField('mailBox', name, '존재하지 않는 메일함입니다');
throw new ErrorResponse(ERROR_CODE.MAILBOX_NOT_FOUND, errorField);
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion server/src/v1/mail/box/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const createBox = async (user, name) => {
user_no: user.no,
name,
});

addMailBox({ user, name });
return response.get({ plain: true });
};
Expand All @@ -28,7 +29,6 @@ const updateBox = async (user, boxNo, oldName, newName) => {
boxRow.name = newName;
await boxRow.save();
renameMailBox({ user, oldName, newName });

return boxRow;
};

Expand Down
4 changes: 2 additions & 2 deletions server/src/v1/mail/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const DEFAULT_MAIL_QUERY_OPTIONS = {
};

const SORT_TYPE = {
datedesc: [['no', 'DESC']],
dateasc: [['no', 'ASC']],
datedesc: [[DB.MailTemplate, 'createdAt', 'DESC']],
dateasc: [[DB.MailTemplate, 'createdAt', 'ASC']],
subjectdesc: [[DB.MailTemplate, 'subject', 'DESC']],
subjectasc: [[DB.MailTemplate, 'subject', 'ASC']],
fromdesc: [[DB.MailTemplate, 'from', 'DESC']],
Expand Down
2 changes: 0 additions & 2 deletions server/test/libraries/mail/attachment.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ describe('attachment validation...', () => {
try {
checkAttachment(files);
} catch (err) {
console.log(err);
const { errorCode, fieldErrors } = err;
errorCode.status.should.be.equals(400);
errorCode.message.should.be.equals('INVALID INPUT VALUE');
Expand Down Expand Up @@ -105,7 +104,6 @@ describe('attachment validation...', () => {
try {
checkAttachment(files);
} catch (err) {
console.log(err);
const { errorCode, fieldErrors } = err;
errorCode.status.should.be.equals(400);
errorCode.message.should.be.equals('INVALID INPUT VALUE');
Expand Down
8 changes: 6 additions & 2 deletions server/test/mail/api.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,19 @@ describe('Mail api test...', () => {
it('# sort가 datedesc면 받은 시간 역순으로 출력한다. ', done => {
authenticatedUser.get('/mail?sort=datedesc').end((err, { body }) => {
const { mails } = body;
mails[0].no.should.be.above(mails[1].no);
const mail0 = new Date(mails[0].MailTemplate.createdAt).getTime();
const mail1 = new Date(mails[1].MailTemplate.createdAt).getTime();
mail0.should.be.aboveOrEqual(mail1);
done();
});
});

it('# sort가 dateasc면 받은 시간순으로 출력한다. ', done => {
authenticatedUser.get('/mail?sort=dateasc').end((err, { body }) => {
const { mails } = body;
mails[0].no.should.be.below(mails[1].no);
const mail0 = new Date(mails[0].MailTemplate.createdAt).getTime();
const mail1 = new Date(mails[1].MailTemplate.createdAt).getTime();
mail0.should.be.belowOrEqual(mail1);
done();
});
});
Expand Down
8 changes: 4 additions & 4 deletions server/test/mail/service.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ describe('Mail Service Test', () => {
it('# 매개변수 오브젝트에 sort가 dateasc면 no asc 이다...', () => {
const query = service.getQueryByOptions({ ...data, sort: 'dateasc' });
const order = query.order.flat();
order[0].should.be.equals('no');
order[1].should.be.equals('ASC');
order[1].should.be.equals('createdAt');
order[2].should.be.equals('ASC');
});

it('# 매개변수 오브젝트에 sort가 datedesc면 no desc 이다...', () => {
const query = service.getQueryByOptions({ ...data, sort: 'datedesc' });
const order = query.order.flat();
order[0].should.be.equals('no');
order[1].should.be.equals('DESC');
order[1].should.be.equals('createdAt');
order[2].should.be.equals('DESC');
});

it('# 매개변수 오브젝트에 sort가 유효한 값이 아니면 order는 존재하지 않는다...', () => {
Expand Down
12 changes: 9 additions & 3 deletions web/components/Aside/dialog-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const getDialogData = (
title: '메일함 추가',
textContents: '추가할 메일함 이름을 적어주세요',
needTextField: true,
okBtnHandler: async (name, handleSnackbarState) => {
okBtnHandler: async (name, handleSnackbarState, setDialogOkButtonDisableState) => {
let errorMessage = '';
if (!errorMessage && customCategory.find(category => category.name === name)) {
errorMessage = SNACKBAR_MSG.ERROR.DUPLICATE;
Expand All @@ -48,10 +48,12 @@ export const getDialogData = (
dispatch(handleSnackbarState(getSnackbarState(SNACKBAR_VARIANT.ERROR, errorMessage)));
return;
}
setDialogOkButtonDisableState(true);
const { isError, data } = await request.post(url, { name });
if (isError) {
const { message } = errorParser(data);
dispatch(handleSnackbarState(getSnackbarState(SNACKBAR_VARIANT.ERROR, message)));
setDialogOkButtonDisableState(false);
return;
}
const { name: createdName, no } = data.createdBox;
Expand All @@ -72,7 +74,7 @@ export const getDialogData = (
title: `메일함(${customCategory[idx].name}) 변경`,
textContents: '변경할 메일함 이름을 적어주세요',
needTextField: true,
okBtnHandler: async (name, handleSnackbarState) => {
okBtnHandler: async (name, handleSnackbarState, setDialogOkButtonDisableState) => {
let errorMessage = '';
if (!errorMessage && customCategory.find(category => category.name === name)) {
errorMessage = SNACKBAR_MSG.ERROR.DUPLICATE;
Expand All @@ -87,13 +89,15 @@ export const getDialogData = (
dispatch(handleSnackbarState(getSnackbarState(SNACKBAR_VARIANT.ERROR, errorMessage)));
return;
}
setDialogOkButtonDisableState(true);
const { isError, data } = await request.patch(url + customCategory[idx].no, {
oldName: customCategory[idx].name,
newName: name,
});
if (isError) {
const { message } = errorParser(data);
dispatch(handleSnackbarState(getSnackbarState(SNACKBAR_VARIANT.ERROR, message)));
setDialogOkButtonDisableState(false);
return;
}
customCategory[idx].name = name;
Expand All @@ -111,13 +115,15 @@ export const getDialogData = (
title: `메일함(${customCategory[idx].name}) 삭제`,
textContents: '정말로 삭제하시겠습니까?',
needTextField: false,
okBtnHandler: async (_, handleSnackbarState) => {
okBtnHandler: async (_, handleSnackbarState, setDialogOkButtonDisableState) => {
setDialogOkButtonDisableState(true);
const { no, name } = customCategory[idx];
const query = `?name=${name}`;
const { isError, data } = await request.delete(url + no + query);
if (isError) {
const { message } = errorParser(data);
dispatch(handleSnackbarState(getSnackbarState(SNACKBAR_VARIANT.ERROR, message)));
setDialogOkButtonDisableState(false);
return;
}
dispatch(
Expand Down
21 changes: 13 additions & 8 deletions web/components/Aside/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext, useState, useEffect } from 'react';
import React, { useContext, useState, useMemo } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import {
List,
Expand Down Expand Up @@ -72,30 +72,27 @@ const Aside = () => {
const [mailboxFolderOpen, setMailboxFolderOpen] = useState(true);
const { state } = useContext(AppStateContext);
const { dispatch } = useContext(AppDispatchContext);
const [dialogOkButtonDisableState, setDialogOkButtonDisableState] = useState(false);
const [dialogOpen, setDialogOpen] = useState(false);
const [dialogState, setDialogState] = useState(getDialogData(0));
const [dialogTextFieldState, setDialogTextFieldState] = useState('');

const fetchingCategories = useFetch(URL);

useEffect(() => {
useMemo(() => {
if (fetchingCategories.data) {
dispatch(handleCategoriesChange({ ...fetchingCategories.data }));
}
}, [dispatch, fetchingCategories.data]);

if (fetchingCategories.loading) {
if (fetchingCategories.loading || !state.categories) {
return <Loading />;
}

if (fetchingCategories.error) {
return errorHandler(fetchingCategories.error);
}

if (!state.categories) {
return <Loading />;
}

const iconOfDefaultCategories = [
selected => <AllInboxIcon className={selected ? classes.whiteIcon : ''} />,
selected => <StarBorder className={selected ? classes.whiteIcon : ''} />,
Expand All @@ -114,6 +111,7 @@ const Aside = () => {
dispatch,
);
if (!dialogData) return;
setDialogOkButtonDisableState(false);
setDialogState(dialogData);
setDialogOpen(true);
};
Expand Down Expand Up @@ -221,7 +219,14 @@ const Aside = () => {
</DialogContent>
<DialogActions>
<Button
onClick={() => dialogState.okBtnHandler(dialogTextFieldState, handleSnackbarState)}
disabled={dialogOkButtonDisableState}
onClick={() =>
dialogState.okBtnHandler(
dialogTextFieldState.trim(),
handleSnackbarState,
setDialogOkButtonDisableState,
)
}
color="primary">
확인
</Button>
Expand Down
2 changes: 1 addition & 1 deletion web/components/MailArea/MailTemplate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const splitMoment = value =>

const getDateOrTime = createdAt => {
const [year, month, day] = splitMoment(createdAt);
const [nowYear, nowDay] = splitMoment();
const [nowYear, nowMonth, nowDay] = splitMoment();
const time = moment(createdAt).format('HH:mm');
let date;
if (day !== nowDay) date = `${month}-${day}`;
Expand Down
Loading

0 comments on commit 521e971

Please sign in to comment.