From 453f13f3db9445b1dd568cbfc18182d6c158af3c Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 9 Oct 2019 16:30:52 +0700 Subject: [PATCH] letting only to add tags --- src/components/node/Tags/index.tsx | 42 ++++++++++++++++-------------- src/redux/node/actions.ts | 7 ++++- src/redux/node/constants.ts | 1 + src/redux/node/handlers.ts | 5 ++++ src/redux/node/sagas.ts | 12 +++++++-- 5 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/components/node/Tags/index.tsx b/src/components/node/Tags/index.tsx index cf698ff6..76b3299a 100644 --- a/src/components/node/Tags/index.tsx +++ b/src/components/node/Tags/index.tsx @@ -25,7 +25,7 @@ type IProps = HTMLAttributes & { export const Tags: FC = ({ tags, is_editable, onTagsChange, ...props }) => { const [input, setInput] = useState(''); - const [data, setData] = useState(tags); + const [data, setData] = useState([]); const timer = useRef(null); const onInput = useCallback( @@ -51,6 +51,7 @@ export const Tags: FC = ({ tags, is_editable, onTagsChange, ...props }) .split(',') .map((title: string) => title.trim().substr(0, 32)) .filter(el => el.length > 0) + .filter(el => !tags.some(tag => tag.title.trim() === el.trim())) .map(title => ({ title, })), @@ -63,36 +64,39 @@ export const Tags: FC = ({ tags, is_editable, onTagsChange, ...props }) ); const onSubmit = useCallback(() => { - if (length(tags) === length(data) && isEmpty(symmetricDifference(tags, data))) return; + if (!data.length) return; + onTagsChange(uniq([...tags, ...data]).map(tag => tag.title)); + }, [tags, data, onTagsChange]); - if (timer.current) clearTimeout(timer.current); + // const onBlur = useCallback(() => { + // clearTimeout(timer.current); + // onSubmit(); + // }, [onSubmit, timer]); - onTagsChange(data.map(tag => tag.title)); - }, [tags, data, onTagsChange, timer]); + // useEffect(() => { + // timer.current = setTimeout(() => { + // onSubmit(); + // }, 3000); - const onBlur = useCallback(() => { - clearTimeout(timer.current); - onSubmit(); - }, [onSubmit, timer]); + // return () => { + // clearTimeout(timer.current); + // }; + // }, [data]); - useEffect(() => setData(tags), [tags]); useEffect(() => { - timer.current = setTimeout(() => { - onSubmit(); - }, 3000); - - return () => { - clearTimeout(timer.current); - }; - }, [data, tags]); + setData(data.filter(({ title }) => !tags.some(tag => tag.title.trim() === title.trim()))); + }, [tags]); return ( + {tags.map(tag => ( + + ))} {data.map(tag => ( ))} - {is_editable && } + {is_editable && } ); }; diff --git a/src/redux/node/actions.ts b/src/redux/node/actions.ts index e8a7603d..2e7e29f7 100644 --- a/src/redux/node/actions.ts +++ b/src/redux/node/actions.ts @@ -1,4 +1,4 @@ -import { INode, IValidationErrors, IComment } from '../types'; +import { INode, IValidationErrors, IComment, ITag } from '../types'; import { NODE_ACTIONS } from './constants'; import { INodeState } from './reducer'; @@ -59,3 +59,8 @@ export const nodeUpdateTags = (id: INode['id'], tags: string[]) => ({ id, tags, }); + +export const nodeSetTags = (tags: ITag[]) => ({ + type: NODE_ACTIONS.SET_TAGS, + tags, +}); diff --git a/src/redux/node/constants.ts b/src/redux/node/constants.ts index 2f9825a3..106e1417 100644 --- a/src/redux/node/constants.ts +++ b/src/redux/node/constants.ts @@ -18,6 +18,7 @@ export const NODE_ACTIONS = { SET_COMMENTS: `${prefix}SET_COMMENTS`, UPDATE_TAGS: `${prefix}UPDATE_TAGS`, + SET_TAGS: `${prefix}SET_TAGS`, }; export const EMPTY_BLOCK: IBlock = { diff --git a/src/redux/node/handlers.ts b/src/redux/node/handlers.ts index 876f070f..813d53c7 100644 --- a/src/redux/node/handlers.ts +++ b/src/redux/node/handlers.ts @@ -8,6 +8,7 @@ import { nodeSetSendingComment, nodeSetComments, nodeSetCommentData, + nodeSetTags, } from './actions'; import { INodeState } from './reducer'; @@ -38,6 +39,9 @@ const setCommentData = ( { id, comment }: ReturnType ) => assocPath(['comment_data', id], comment, state); +const setTags = (state: INodeState, { tags }: ReturnType) => + assocPath(['current', 'tags'], tags, state); + export const NODE_HANDLERS = { [NODE_ACTIONS.SAVE]: setSaveErrors, [NODE_ACTIONS.SET_LOADING]: setLoading, @@ -46,4 +50,5 @@ export const NODE_HANDLERS = { [NODE_ACTIONS.SET_SENDING_COMMENT]: setSendingComment, [NODE_ACTIONS.SET_COMMENTS]: setComments, [NODE_ACTIONS.SET_COMMENT_DATA]: setCommentData, + [NODE_ACTIONS.SET_TAGS]: setTags, }; diff --git a/src/redux/node/sagas.ts b/src/redux/node/sagas.ts index b78e7916..94ff4038 100644 --- a/src/redux/node/sagas.ts +++ b/src/redux/node/sagas.ts @@ -14,6 +14,7 @@ import { nodeSetComments, nodeSetCommentData, nodeUpdateTags, + nodeSetTags, } from './actions'; import { postNode, getNode, postNodeComment, getNodeComments, updateNodeTags } from './api'; import { reqWrapper } from '../auth/sagas'; @@ -23,6 +24,7 @@ import { modalSetShown } from '../modal/actions'; import { selectFlowNodes } from '../flow/selectors'; import { URLS } from '~/constants/urls'; import { selectNode } from './selectors'; +import { IResultWithStatus, INode } from '../types'; function* onNodeSave({ node }: ReturnType) { yield put(nodeSetSaveErrors({})); @@ -105,9 +107,15 @@ function* onPostComment({ id }: ReturnType) { function* onUpdateTags({ id, tags }: ReturnType) { yield delay(1000); - const result = yield call(reqWrapper, updateNodeTags, { id, tags }); + const { + data: { node }, + }: IResultWithStatus<{ node: INode }> = yield call(reqWrapper, updateNodeTags, { id, tags }); - console.log({ result }); + const { current } = yield select(selectNode); + + if (!node || !node.id || node.id !== current.id) return; + + yield put(nodeSetTags(node.tags)); } export default function* nodeSaga() {