Files
payload/src/admin/components/forms/Form/fieldReducer.js

132 lines
3.6 KiB
JavaScript

import { unflatten, flatten } from 'flatley';
import flattenFilters from './flattenFilters';
const unflattenRowsFromState = (state, path) => {
// Take a copy of state
const remainingFlattenedState = { ...state };
const rowsFromStateObject = {};
const pathPrefixToRemove = path.substring(0, path.lastIndexOf('.') + 1);
// Loop over all keys from state
// If the key begins with the name of the parent field,
// Add value to rowsFromStateObject and delete it from remaining state
Object.keys(state).forEach((key) => {
if (key.indexOf(`${path}.`) === 0) {
if (!state[key].ignoreWhileFlattening) {
const name = key.replace(pathPrefixToRemove, '');
rowsFromStateObject[name] = state[key];
rowsFromStateObject[name].initialValue = rowsFromStateObject[name].value;
}
delete remainingFlattenedState[key];
}
});
const unflattenedRows = unflatten(rowsFromStateObject);
return {
unflattenedRows: unflattenedRows[path.replace(pathPrefixToRemove, '')] || [],
remainingFlattenedState,
};
};
function fieldReducer(state, action) {
switch (action.type) {
case 'REPLACE_STATE': {
return action.state;
}
case 'REMOVE': {
const newState = { ...state };
delete newState[action.path];
return newState;
}
case 'REMOVE_ROW': {
const { rowIndex, path } = action;
const { unflattenedRows, remainingFlattenedState } = unflattenRowsFromState(state, path);
unflattenedRows.splice(rowIndex, 1);
const flattenedRowState = unflattenedRows.length > 0 ? flatten({ [path]: unflattenedRows }, { filters: flattenFilters }) : {};
return {
...remainingFlattenedState,
...flattenedRowState,
};
}
case 'ADD_ROW': {
const {
rowIndex, path, subFieldState, blockType,
} = action;
const { unflattenedRows, remainingFlattenedState } = unflattenRowsFromState(state, path);
if (blockType) {
subFieldState.blockType = {
value: blockType,
initialValue: blockType,
valid: true,
};
subFieldState.blockName = {
value: null,
initialValue: null,
valid: true,
};
}
// Add new object containing subfield names to unflattenedRows array
unflattenedRows.splice(rowIndex + 1, 0, subFieldState);
const newState = {
...remainingFlattenedState,
...(flatten({ [path]: unflattenedRows }, { filters: flattenFilters })),
};
return newState;
}
case 'MOVE_ROW': {
const { moveFromIndex, moveToIndex, path } = action;
const { unflattenedRows, remainingFlattenedState } = unflattenRowsFromState(state, path);
// copy the row to move
const copyOfMovingRow = unflattenedRows[moveFromIndex];
// delete the row by index
unflattenedRows.splice(moveFromIndex, 1);
// insert row copyOfMovingRow back in
unflattenedRows.splice(moveToIndex, 0, copyOfMovingRow);
const newState = {
...remainingFlattenedState,
...(flatten({ [path]: unflattenedRows }, { filters: flattenFilters })),
};
return newState;
}
default: {
const newField = {
value: action.value,
valid: action.valid,
errorMessage: action.errorMessage,
disableFormData: action.disableFormData,
ignoreWhileFlattening: action.ignoreWhileFlattening,
initialValue: action.initialValue,
stringify: action.stringify,
validate: action.validate,
};
return {
...state,
[action.path]: newField,
};
}
}
}
export default fieldReducer;