1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-26 05:16:41 +07:00

added tag autocomplete

This commit is contained in:
Fedor Katurov 2020-10-31 20:49:28 +07:00
parent 1414245a1a
commit 359cfaee7a
18 changed files with 375 additions and 80 deletions

View file

@ -7,6 +7,17 @@ export const tagSetNodes = (nodes: Partial<ITagState['nodes']>) => ({
});
export const tagLoadNodes = (tag: string) => ({
type: TAG_ACTIONS.LOAD_TAG_NODES,
type: TAG_ACTIONS.LOAD_NODES,
tag,
});
export const tagSetAutocomplete = (autocomplete: Partial<ITagState['autocomplete']>) => ({
type: TAG_ACTIONS.SET_TAG_AUTOCOMPLETE,
autocomplete,
});
export const tagLoadAutocomplete = (search: string, exclude: string[]) => ({
type: TAG_ACTIONS.LOAD_AUTOCOMPLETE,
search,
exclude,
});

View file

@ -17,3 +17,17 @@ export const getTagNodes = ({
.get(API.TAG.NODES, configWithToken(access, { params: { name: tag, offset, limit } }))
.then(resultMiddleware)
.catch(errorMiddleware);
export const getTagAutocomplete = ({
search,
exclude,
access,
}: {
access: string;
search: string;
exclude: string[];
}): Promise<IResultWithStatus<{ tags: string[] }>> =>
api
.get(API.TAG.AUTOCOMPLETE, configWithToken(access, { params: { search, exclude } }))
.then(resultMiddleware)
.catch(errorMiddleware);

View file

@ -1,6 +1,8 @@
const prefix = 'TAG.';
export const TAG_ACTIONS = {
LOAD_TAG_NODES: `${prefix}LOAD_TAG_NODES`,
LOAD_NODES: `${prefix}LOAD_TAG_NODES`,
SET_TAG_NODES: `${prefix}SET_TAG_NODES`,
SET_TAG_AUTOCOMPLETE: `${prefix}SET_TAG_NODES`,
LOAD_AUTOCOMPLETE: `${prefix}LOAD_TAG_AUTOCOMPLETE`,
};

View file

@ -1,6 +1,6 @@
import { TAG_ACTIONS } from '~/redux/tag/constants';
import { ITagState } from '~/redux/tag/index';
import { tagSetNodes } from '~/redux/tag/actions';
import { tagSetAutocomplete, tagSetNodes } from '~/redux/tag/actions';
const setNodes = (state: ITagState, { nodes }: ReturnType<typeof tagSetNodes>) => ({
...state,
@ -10,6 +10,18 @@ const setNodes = (state: ITagState, { nodes }: ReturnType<typeof tagSetNodes>) =
},
});
const setAutocomplete = (
state: ITagState,
{ autocomplete }: ReturnType<typeof tagSetAutocomplete>
) => ({
...state,
autocomplete: {
...state.autocomplete,
...autocomplete,
},
});
export const TAG_HANDLERS = {
[TAG_ACTIONS.SET_TAG_NODES]: setNodes,
[TAG_ACTIONS.SET_TAG_AUTOCOMPLETE]: setAutocomplete,
};

View file

@ -8,6 +8,10 @@ export interface ITagState {
count: number;
isLoading: boolean;
};
autocomplete: {
isLoading: boolean;
options: string[];
};
}
const INITIAL_STATE: ITagState = {
@ -16,6 +20,10 @@ const INITIAL_STATE: ITagState = {
count: 0,
isLoading: true,
},
autocomplete: {
isLoading: true,
options: [],
},
};
export default createReducer(INITIAL_STATE, TAG_HANDLERS);

View file

@ -1,9 +1,9 @@
import { TAG_ACTIONS } from '~/redux/tag/constants';
import { call, put, select, takeLatest } from 'redux-saga/effects';
import { tagLoadNodes, tagSetNodes } from '~/redux/tag/actions';
import { call, delay, put, select, takeLatest } from 'redux-saga/effects';
import { tagLoadAutocomplete, tagLoadNodes, tagSetAutocomplete, tagSetNodes, } from '~/redux/tag/actions';
import { reqWrapper } from '~/redux/auth/sagas';
import { selectTagNodes } from '~/redux/tag/selectors';
import { getTagNodes } from '~/redux/tag/api';
import { getTagAutocomplete, getTagNodes } from '~/redux/tag/api';
import { Unwrap } from '~/redux/types';
function* loadTagNodes({ tag }: ReturnType<typeof tagLoadNodes>) {
@ -26,6 +26,28 @@ function* loadTagNodes({ tag }: ReturnType<typeof tagLoadNodes>) {
}
}
export default function* tagSaga() {
yield takeLatest(TAG_ACTIONS.LOAD_TAG_NODES, loadTagNodes);
function* loadAutocomplete({ search, exclude }: ReturnType<typeof tagLoadAutocomplete>) {
if (search.length < 3) return;
try {
yield put(tagSetAutocomplete({ isLoading: true }));
yield delay(100);
const { data, error }: Unwrap<ReturnType<typeof getTagAutocomplete>> = yield call(
reqWrapper,
getTagAutocomplete,
{ search, exclude }
);
if (error) throw new Error(error);
yield put(tagSetAutocomplete({ options: data.tags, isLoading: false }));
} catch (e) {
yield put(tagSetAutocomplete({ isLoading: false }));
}
}
export default function* tagSaga() {
yield takeLatest(TAG_ACTIONS.LOAD_NODES, loadTagNodes);
yield takeLatest(TAG_ACTIONS.LOAD_AUTOCOMPLETE, loadAutocomplete);
}

View file

@ -2,3 +2,4 @@ import { IState } from '~/redux/store';
export const selectTag = (state: IState) => state.tag;
export const selectTagNodes = (state: IState) => state.tag.nodes;
export const selectTagAutocomplete = (state: IState) => state.tag.autocomplete;