mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-26 05:16:41 +07:00
NodeLayout
This commit is contained in:
parent
684a4f4474
commit
b154277de8
23 changed files with 332 additions and 65 deletions
|
@ -1,5 +1,6 @@
|
|||
import { INode, IValidationErrors } from '../types';
|
||||
import { NODE_ACTIONS } from './constants';
|
||||
import { INodeState } from './reducer';
|
||||
|
||||
export const nodeSave = (node: INode) => ({
|
||||
node,
|
||||
|
@ -10,3 +11,13 @@ export const nodeSetSaveErrors = (errors: IValidationErrors) => ({
|
|||
errors,
|
||||
type: NODE_ACTIONS.SET_SAVE_ERRORS,
|
||||
});
|
||||
|
||||
export const nodeLoadNode = (id: string | number) => ({
|
||||
id,
|
||||
type: NODE_ACTIONS.LOAD_NODE,
|
||||
});
|
||||
|
||||
export const nodeSetLoading = (is_loading: INodeState['is_loading']) => ({
|
||||
is_loading,
|
||||
type: NODE_ACTIONS.SET_LOADING,
|
||||
});
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
import { IBlock, INode } from '../types';
|
||||
import { IBlock, INode, ValueOf } from '../types';
|
||||
import { NodeImageBlock } from '~/components/node/NodeImageBlock';
|
||||
import { NodeImageBlockPlaceholder } from '~/components/node/NodeImageBlockPlaceholder';
|
||||
import { ReactElement, FC } from 'react';
|
||||
|
||||
const prefix = 'NODE.';
|
||||
export const NODE_ACTIONS = {
|
||||
SAVE: 'NODE.SAVE',
|
||||
SET_SAVE_ERRORS: 'NODE.SET_SAVE_ERRORS',
|
||||
SAVE: `${prefix}NODE.SAVE`,
|
||||
LOAD_NODE: `${prefix}LOAD_NODE`,
|
||||
|
||||
SET_SAVE_ERRORS: `${prefix}NODE.SET_SAVE_ERRORS`,
|
||||
SET_LOADING: `${prefix}NODE.SET_LOADING`,
|
||||
};
|
||||
|
||||
export const EMPTY_BLOCK: IBlock = {
|
||||
|
@ -32,3 +39,22 @@ export const EMPTY_NODE: INode = {
|
|||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const NODE_TYPES = {
|
||||
IMAGE: 'image',
|
||||
AUDIO: 'audio',
|
||||
VIDEO: 'video',
|
||||
TEXT: 'text',
|
||||
};
|
||||
|
||||
type INodeComponents = Record<
|
||||
ValueOf<typeof NODE_TYPES>,
|
||||
Record<'component' | 'placeholder', FC<{ node: INode }>>
|
||||
>;
|
||||
|
||||
export const NODE_COMPONENTS: INodeComponents = {
|
||||
[NODE_TYPES.IMAGE]: {
|
||||
component: NodeImageBlock,
|
||||
placeholder: NodeImageBlockPlaceholder,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import assocPath from 'ramda/es/assocPath';
|
||||
import { NODE_ACTIONS } from './constants';
|
||||
import { nodeSetSaveErrors } from './actions';
|
||||
import { nodeSetSaveErrors, nodeSetLoading } from './actions';
|
||||
import { INodeState } from './reducer';
|
||||
|
||||
const setSaveErrors = (state: INodeState, { errors }: ReturnType<typeof nodeSetSaveErrors>) => assocPath(['errors'], errors, state);
|
||||
const setSaveErrors = (state: INodeState, { errors }: ReturnType<typeof nodeSetSaveErrors>) =>
|
||||
assocPath(['errors'], errors, state);
|
||||
const setLoading = (state: INodeState, { is_loading }: ReturnType<typeof nodeSetLoading>) =>
|
||||
assocPath(['is_loading'], is_loading, state);
|
||||
|
||||
export const NODE_HANDLERS = {
|
||||
[NODE_ACTIONS.SAVE]: setSaveErrors,
|
||||
[NODE_ACTIONS.SET_LOADING]: setLoading,
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ import { EMPTY_FILE } from '../uploads/constants';
|
|||
export type INodeState = Readonly<{
|
||||
is_loading: boolean;
|
||||
editor: INode;
|
||||
current: INode;
|
||||
error: string;
|
||||
errors: Record<string, string>;
|
||||
}>;
|
||||
|
@ -19,6 +20,7 @@ const INITIAL_STATE: INodeState = {
|
|||
blocks: [],
|
||||
files: [],
|
||||
},
|
||||
current: null,
|
||||
is_loading: false,
|
||||
error: null,
|
||||
errors: {},
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import { takeLatest, call, put, select } from 'redux-saga/effects';
|
||||
import { NODE_ACTIONS } from './constants';
|
||||
import { nodeSave, nodeSetSaveErrors } from './actions';
|
||||
import { nodeSave, nodeSetSaveErrors, nodeLoadNode, nodeSetLoading } from './actions';
|
||||
import { postNode } from './api';
|
||||
import { reqWrapper } from '../auth/sagas';
|
||||
import { flowSetNodes } from '../flow/actions';
|
||||
import { ERRORS } from '~/constants/errors';
|
||||
import { modalSetShown } from '../modal/actions';
|
||||
import { selectFlowNodes } from '../flow/selectors';
|
||||
import { push } from 'connected-react-router';
|
||||
import { URLS } from '~/constants/urls';
|
||||
|
||||
function* onNodeSave({ node }: ReturnType<typeof nodeSave>) {
|
||||
yield put(nodeSetSaveErrors({}));
|
||||
|
@ -28,6 +30,14 @@ function* onNodeSave({ node }: ReturnType<typeof nodeSave>) {
|
|||
return yield put(modalSetShown(false));
|
||||
}
|
||||
|
||||
function* onNodeLoad({ id }: ReturnType<typeof nodeLoadNode>) {
|
||||
yield put(nodeSetLoading(true));
|
||||
yield put(nodeSetSaveErrors({}));
|
||||
|
||||
yield put(push(URLS.NODE_URL(id)));
|
||||
}
|
||||
|
||||
export default function* nodeSaga() {
|
||||
yield takeLatest(NODE_ACTIONS.SAVE, onNodeSave);
|
||||
yield takeLatest(NODE_ACTIONS.LOAD_NODE, onNodeLoad);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue