WIP: implementation of react-diff-viewer for viewing config changes
parent
705599daaf
commit
b2f4a0a024
|
@ -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 = () => {
|
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;
|
export default ConfigPage;
|
|
@ -7,10 +7,46 @@
|
||||||
import { request } from 'strapi-helper-plugin';
|
import { request } from 'strapi-helper-plugin';
|
||||||
import { Map } from 'immutable';
|
import { Map } from 'immutable';
|
||||||
|
|
||||||
// export const EXAMPLE_ACTION = 'EXAMPLE_ACTION';
|
export function getAllDatabaseConfig() {
|
||||||
// export function exampleAction(value) {
|
return async function(dispatch) {
|
||||||
// return {
|
try {
|
||||||
// type: EXAMPLE_ACTION,
|
const data = await request('/config/all/from-database', { method: 'GET' });
|
||||||
// value,
|
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,
|
||||||
|
};
|
||||||
|
}
|
|
@ -5,15 +5,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fromJS, Map } from 'immutable';
|
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) {
|
export default function configReducer(state = initialState, action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case EXAMPLE_ACTION:
|
case SET_DATABASE_CONFIG_IN_STATE:
|
||||||
return 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:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,22 @@
|
||||||
"config": {
|
"config": {
|
||||||
"policies": []
|
"policies": []
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/all/from-files",
|
||||||
|
"handler": "config.getConfigsFromFiles",
|
||||||
|
"config": {
|
||||||
|
"policies": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/all/from-database",
|
||||||
|
"handler": "config.getConfigsFromDatabase",
|
||||||
|
"config": {
|
||||||
|
"policies": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,5 +51,55 @@ module.exports = {
|
||||||
ctx.send({
|
ctx.send({
|
||||||
message: 'Config was successfully imported.'
|
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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"immutable": "^4.0.0-rc.12",
|
"immutable": "^4.0.0-rc.12",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
|
"react-diff-viewer": "^3.1.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-redux": "^7.2.2",
|
"react-redux": "^7.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
|
|
Loading…
Reference in New Issue