WIP: implementation of react-diff-viewer for viewing config changes

pull/1/head
Boaz Poolman 2021-03-20 03:20:48 +01:00
parent 705599daaf
commit b2f4a0a024
6 changed files with 147 additions and 14 deletions

View File

@ -1,7 +1,31 @@
import React from 'react';
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import ReactDiffViewer from 'react-diff-viewer';
import { Map } from 'immutable';
import { getAllDatabaseConfig, getAllFileConfig } from '../../state/actions/Config';
const ConfigPage = () => {
return <div>Config diff</div>
const dispatch = useDispatch();
const fileConfig = useSelector((state) => state.getIn(['config', 'fileConfig']), Map());
const databaseConfig = useSelector((state) => state.getIn(['config', 'databaseConfig']), Map());
useEffect(() => {
dispatch(getAllDatabaseConfig());
dispatch(getAllFileConfig());
}, []);
if (!fileConfig || !databaseConfig) {
return null;
}
return (
<ReactDiffViewer
oldValue={JSON.stringify(fileConfig.get('plugin_users-permissions_email'), null, 2)}
newValue={JSON.stringify(databaseConfig.get('plugin_users-permissions_email'), null, 2)}
splitView={true}
/>
);
}
export default ConfigPage;

View File

@ -7,10 +7,46 @@
import { request } from 'strapi-helper-plugin';
import { Map } from 'immutable';
// export const EXAMPLE_ACTION = 'EXAMPLE_ACTION';
// export function exampleAction(value) {
// return {
// type: EXAMPLE_ACTION,
// value,
// };
// }
export function getAllDatabaseConfig() {
return async function(dispatch) {
try {
const data = await request('/config/all/from-database', { method: 'GET' });
dispatch(setDatabaseConfigInState(data));
strapi.notification.success('woop!');
} catch(err) {
console.log(err);
strapi.notification.error('notification.error');
}
}
}
export function getAllFileConfig() {
return async function(dispatch) {
try {
const data = await request('/config/all/from-files', { method: 'GET' });
dispatch(setFileConfigInState(data));
strapi.notification.success('woop!');
} catch(err) {
console.log(err);
strapi.notification.error('notification.error');
}
}
}
export const SET_DATABASE_CONFIG_IN_STATE = 'SET_DATABASE_CONFIG_IN_STATE';
export function setDatabaseConfigInState(config) {
return {
type: SET_DATABASE_CONFIG_IN_STATE,
config,
};
}
export const SET_FILE_CONFIG_IN_STATE = 'SET_FILE_CONFIG_IN_STATE';
export function setFileConfigInState(config) {
return {
type: SET_FILE_CONFIG_IN_STATE,
config,
};
}

View File

@ -5,15 +5,21 @@
*/
import { fromJS, Map } from 'immutable';
import { EXAMPLE_ACTION } from '../../actions/Config';
import { SET_DATABASE_CONFIG_IN_STATE, SET_FILE_CONFIG_IN_STATE } from '../../actions/Config';
const initialState = fromJS({});
const initialState = fromJS({
databaseConfig: Map({}),
fileConfig: Map({})
});
export default function configReducer(state = initialState, action) {
switch (action.type) {
case EXAMPLE_ACTION:
case SET_DATABASE_CONFIG_IN_STATE:
return state
.update('value', () => action.value)
.update('databaseConfig', () => fromJS(action.config))
case SET_FILE_CONFIG_IN_STATE:
return state
.update('fileConfig', () => fromJS(action.config))
default:
return state;
}

View File

@ -15,6 +15,22 @@
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/all/from-files",
"handler": "config.getConfigsFromFiles",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/all/from-database",
"handler": "config.getConfigsFromDatabase",
"config": {
"policies": []
}
}
]
}

View File

@ -51,5 +51,55 @@ module.exports = {
ctx.send({
message: 'Config was successfully imported.'
});
},
/**
* Get all configs as defined in your filesystem.
*
* @param {object} ctx - Request context object.
* @returns {object} Object with key value pairs of configs.
*/
getConfigsFromFiles: async (ctx) => {
// Check for existance of the config file destination dir.
if (!fs.existsSync(strapi.plugins.config.config.destination)) {
ctx.send({
message: 'No config files were found.'
});
return;
}
const configFiles = fs.readdirSync(strapi.plugins.config.config.destination);
let formattedConfigs = {};
const getConfigs = async () => {
return Promise.all(configFiles.map(async (file) => {
const formattedConfigName = file.slice(0, -5); // remove the .json extension.
const fileContents = await strapi.plugins.config.services.config.readConfigFile(formattedConfigName);
formattedConfigs[formattedConfigName] = fileContents;
}));
};
await getConfigs();
ctx.send(formattedConfigs);
},
/**
* Get all configs as defined in your database.
*
* @param {object} ctx - Request context object.
* @returns {object} Object with key value pairs of configs.
*/
getConfigsFromDatabase: async (ctx) => {
const coreStoreAPI = strapi.query('core_store');
const coreStore = await coreStoreAPI.find({ _limit: -1 });
let formattedConfigs = {};
Object.values(coreStore).map(async ({ key, value }) => {
formattedConfigs[key] = JSON.parse(value);
});
ctx.send(formattedConfigs);
}
};

View File

@ -10,6 +10,7 @@
"dependencies": {
"immutable": "^4.0.0-rc.12",
"react": "^17.0.1",
"react-diff-viewer": "^3.1.1",
"react-dom": "^17.0.1",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",