mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
letting only to add tags
This commit is contained in:
parent
9df5e022dd
commit
453f13f3db
5 changed files with 45 additions and 22 deletions
|
@ -25,7 +25,7 @@ type IProps = HTMLAttributes<HTMLDivElement> & {
|
||||||
|
|
||||||
export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props }) => {
|
export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props }) => {
|
||||||
const [input, setInput] = useState('');
|
const [input, setInput] = useState('');
|
||||||
const [data, setData] = useState(tags);
|
const [data, setData] = useState([]);
|
||||||
const timer = useRef(null);
|
const timer = useRef(null);
|
||||||
|
|
||||||
const onInput = useCallback(
|
const onInput = useCallback(
|
||||||
|
@ -51,6 +51,7 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((title: string) => title.trim().substr(0, 32))
|
.map((title: string) => title.trim().substr(0, 32))
|
||||||
.filter(el => el.length > 0)
|
.filter(el => el.length > 0)
|
||||||
|
.filter(el => !tags.some(tag => tag.title.trim() === el.trim()))
|
||||||
.map(title => ({
|
.map(title => ({
|
||||||
title,
|
title,
|
||||||
})),
|
})),
|
||||||
|
@ -63,36 +64,39 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
|
||||||
);
|
);
|
||||||
|
|
||||||
const onSubmit = useCallback(() => {
|
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));
|
// useEffect(() => {
|
||||||
}, [tags, data, onTagsChange, timer]);
|
// timer.current = setTimeout(() => {
|
||||||
|
// onSubmit();
|
||||||
|
// }, 3000);
|
||||||
|
|
||||||
const onBlur = useCallback(() => {
|
// return () => {
|
||||||
clearTimeout(timer.current);
|
// clearTimeout(timer.current);
|
||||||
onSubmit();
|
// };
|
||||||
}, [onSubmit, timer]);
|
// }, [data]);
|
||||||
|
|
||||||
useEffect(() => setData(tags), [tags]);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
timer.current = setTimeout(() => {
|
setData(data.filter(({ title }) => !tags.some(tag => tag.title.trim() === title.trim())));
|
||||||
onSubmit();
|
}, [tags]);
|
||||||
}, 3000);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearTimeout(timer.current);
|
|
||||||
};
|
|
||||||
}, [data, tags]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TagField {...props}>
|
<TagField {...props}>
|
||||||
|
{tags.map(tag => (
|
||||||
|
<Tag key={tag.title} title={tag.title} feature={tag.feature} />
|
||||||
|
))}
|
||||||
{data.map(tag => (
|
{data.map(tag => (
|
||||||
<Tag key={tag.title} title={tag.title} feature={tag.feature} />
|
<Tag key={tag.title} title={tag.title} feature={tag.feature} />
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{is_editable && <Tag title={input} onInput={onInput} onKeyUp={onKeyUp} onBlur={onBlur} />}
|
{is_editable && <Tag title={input} onInput={onInput} onKeyUp={onKeyUp} onBlur={onSubmit} />}
|
||||||
</TagField>
|
</TagField>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { INode, IValidationErrors, IComment } from '../types';
|
import { INode, IValidationErrors, IComment, ITag } from '../types';
|
||||||
import { NODE_ACTIONS } from './constants';
|
import { NODE_ACTIONS } from './constants';
|
||||||
import { INodeState } from './reducer';
|
import { INodeState } from './reducer';
|
||||||
|
|
||||||
|
@ -59,3 +59,8 @@ export const nodeUpdateTags = (id: INode['id'], tags: string[]) => ({
|
||||||
id,
|
id,
|
||||||
tags,
|
tags,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const nodeSetTags = (tags: ITag[]) => ({
|
||||||
|
type: NODE_ACTIONS.SET_TAGS,
|
||||||
|
tags,
|
||||||
|
});
|
||||||
|
|
|
@ -18,6 +18,7 @@ export const NODE_ACTIONS = {
|
||||||
SET_COMMENTS: `${prefix}SET_COMMENTS`,
|
SET_COMMENTS: `${prefix}SET_COMMENTS`,
|
||||||
|
|
||||||
UPDATE_TAGS: `${prefix}UPDATE_TAGS`,
|
UPDATE_TAGS: `${prefix}UPDATE_TAGS`,
|
||||||
|
SET_TAGS: `${prefix}SET_TAGS`,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EMPTY_BLOCK: IBlock = {
|
export const EMPTY_BLOCK: IBlock = {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
nodeSetSendingComment,
|
nodeSetSendingComment,
|
||||||
nodeSetComments,
|
nodeSetComments,
|
||||||
nodeSetCommentData,
|
nodeSetCommentData,
|
||||||
|
nodeSetTags,
|
||||||
} from './actions';
|
} from './actions';
|
||||||
import { INodeState } from './reducer';
|
import { INodeState } from './reducer';
|
||||||
|
|
||||||
|
@ -38,6 +39,9 @@ const setCommentData = (
|
||||||
{ id, comment }: ReturnType<typeof nodeSetCommentData>
|
{ id, comment }: ReturnType<typeof nodeSetCommentData>
|
||||||
) => assocPath(['comment_data', id], comment, state);
|
) => assocPath(['comment_data', id], comment, state);
|
||||||
|
|
||||||
|
const setTags = (state: INodeState, { tags }: ReturnType<typeof nodeSetTags>) =>
|
||||||
|
assocPath(['current', 'tags'], tags, state);
|
||||||
|
|
||||||
export const NODE_HANDLERS = {
|
export const NODE_HANDLERS = {
|
||||||
[NODE_ACTIONS.SAVE]: setSaveErrors,
|
[NODE_ACTIONS.SAVE]: setSaveErrors,
|
||||||
[NODE_ACTIONS.SET_LOADING]: setLoading,
|
[NODE_ACTIONS.SET_LOADING]: setLoading,
|
||||||
|
@ -46,4 +50,5 @@ export const NODE_HANDLERS = {
|
||||||
[NODE_ACTIONS.SET_SENDING_COMMENT]: setSendingComment,
|
[NODE_ACTIONS.SET_SENDING_COMMENT]: setSendingComment,
|
||||||
[NODE_ACTIONS.SET_COMMENTS]: setComments,
|
[NODE_ACTIONS.SET_COMMENTS]: setComments,
|
||||||
[NODE_ACTIONS.SET_COMMENT_DATA]: setCommentData,
|
[NODE_ACTIONS.SET_COMMENT_DATA]: setCommentData,
|
||||||
|
[NODE_ACTIONS.SET_TAGS]: setTags,
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
nodeSetComments,
|
nodeSetComments,
|
||||||
nodeSetCommentData,
|
nodeSetCommentData,
|
||||||
nodeUpdateTags,
|
nodeUpdateTags,
|
||||||
|
nodeSetTags,
|
||||||
} from './actions';
|
} from './actions';
|
||||||
import { postNode, getNode, postNodeComment, getNodeComments, updateNodeTags } from './api';
|
import { postNode, getNode, postNodeComment, getNodeComments, updateNodeTags } from './api';
|
||||||
import { reqWrapper } from '../auth/sagas';
|
import { reqWrapper } from '../auth/sagas';
|
||||||
|
@ -23,6 +24,7 @@ import { modalSetShown } from '../modal/actions';
|
||||||
import { selectFlowNodes } from '../flow/selectors';
|
import { selectFlowNodes } from '../flow/selectors';
|
||||||
import { URLS } from '~/constants/urls';
|
import { URLS } from '~/constants/urls';
|
||||||
import { selectNode } from './selectors';
|
import { selectNode } from './selectors';
|
||||||
|
import { IResultWithStatus, INode } from '../types';
|
||||||
|
|
||||||
function* onNodeSave({ node }: ReturnType<typeof nodeSave>) {
|
function* onNodeSave({ node }: ReturnType<typeof nodeSave>) {
|
||||||
yield put(nodeSetSaveErrors({}));
|
yield put(nodeSetSaveErrors({}));
|
||||||
|
@ -105,9 +107,15 @@ function* onPostComment({ id }: ReturnType<typeof nodePostComment>) {
|
||||||
|
|
||||||
function* onUpdateTags({ id, tags }: ReturnType<typeof nodeUpdateTags>) {
|
function* onUpdateTags({ id, tags }: ReturnType<typeof nodeUpdateTags>) {
|
||||||
yield delay(1000);
|
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() {
|
export default function* nodeSaga() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue