mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 21:06:42 +07:00
added tag autocomplete
This commit is contained in:
parent
1414245a1a
commit
359cfaee7a
18 changed files with 375 additions and 80 deletions
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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`,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue