List all config changes & show diff on click
parent
19bb84df78
commit
5f21ac9fc5
|
@ -0,0 +1,49 @@
|
|||
import React from 'react';
|
||||
import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer';
|
||||
import { AttributeIcon } from '@buffetjs/core';
|
||||
import {
|
||||
HeaderModal,
|
||||
HeaderModalTitle,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
} from 'strapi-helper-plugin';
|
||||
|
||||
const ConfigDiff = ({ isOpen, onClose, onToggle, oldValue, newValue, configName }) => {
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
onClosed={onClose}
|
||||
onToggle={onToggle}
|
||||
>
|
||||
<HeaderModal>
|
||||
<section style={{ alignItems: 'center' }}>
|
||||
<AttributeIcon type='enum' />
|
||||
<HeaderModalTitle style={{ marginLeft: 15 }}>Config changes for {configName}</HeaderModalTitle>
|
||||
</section>
|
||||
</HeaderModal>
|
||||
<ModalBody style={{
|
||||
paddingTop: '0.5rem',
|
||||
paddingBottom: '3rem'
|
||||
}}>
|
||||
<div className="container-fluid">
|
||||
<section style={{ marginTop: 20 }}>
|
||||
<ReactDiffViewer
|
||||
oldValue={JSON.stringify(oldValue, null, 2)}
|
||||
newValue={JSON.stringify(newValue, null, 2)}
|
||||
splitView={true}
|
||||
compareMethod={DiffMethod.WORDS}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<section style={{ alignItems: 'center' }}>
|
||||
|
||||
</section>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default ConfigDiff;
|
|
@ -0,0 +1,66 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Table } from '@buffetjs/core';
|
||||
import difference from '../../helpers/getObjectDiff';
|
||||
import ConfigDiff from '../ConfigDiff';
|
||||
|
||||
const headers = [
|
||||
{
|
||||
name: 'Id',
|
||||
value: 'id',
|
||||
},
|
||||
{
|
||||
name: 'Config name',
|
||||
value: 'name',
|
||||
},
|
||||
{
|
||||
name: 'Database table',
|
||||
value: 'lastname',
|
||||
},
|
||||
{
|
||||
name: 'Change',
|
||||
value: 'change_type',
|
||||
},
|
||||
];
|
||||
|
||||
const ConfigList = ({ fileConfig, databaseConfig }) => {
|
||||
const diff = difference(fileConfig.toJS(), databaseConfig.toJS());
|
||||
const [openModal, setOpenModal] = useState(false);
|
||||
const [originalConfig, setOriginalConfig] = useState({});
|
||||
const [newConfig, setNewConfig] = useState({});
|
||||
const [configName, setConfigName] = useState('');
|
||||
let rows = [];
|
||||
|
||||
Object.keys(diff).map((config) => rows.push({ name: config }));
|
||||
|
||||
const closeModal = () => {
|
||||
setOriginalConfig({});
|
||||
setNewConfig({});
|
||||
setConfigName('');
|
||||
setOpenModal(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ConfigDiff
|
||||
isOpen={openModal}
|
||||
oldValue={originalConfig}
|
||||
newValue={newConfig}
|
||||
onClose={closeModal}
|
||||
onToggle={closeModal}
|
||||
configName={configName}
|
||||
/>
|
||||
<Table
|
||||
headers={headers}
|
||||
onClickRow={(e, data) => {
|
||||
setOriginalConfig(fileConfig.get(data.name));
|
||||
setNewConfig(databaseConfig.get(data.name));
|
||||
setConfigName(data.name);
|
||||
setOpenModal(true);
|
||||
}}
|
||||
rows={rows}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ConfigList;
|
|
@ -6,21 +6,15 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import { NotFound } from 'strapi-helper-plugin';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { store } from "../../helpers/configureStore";
|
||||
import pluginId from '../../helpers/pluginId';
|
||||
import ConfigPage from '../ConfigPage';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<Switch>
|
||||
<Route path={`/plugins/${pluginId}`} component={ConfigPage} exact />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
<ConfigPage />
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
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';
|
||||
import ConfigList from '../../components/ConfigList';
|
||||
|
||||
const ConfigPage = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
@ -15,17 +15,14 @@ const ConfigPage = () => {
|
|||
dispatch(getAllFileConfig());
|
||||
}, []);
|
||||
|
||||
if (!fileConfig || !databaseConfig) {
|
||||
if (fileConfig.size === 0 || databaseConfig.size === 0) {
|
||||
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}
|
||||
disableWordDiff
|
||||
/>
|
||||
<div>
|
||||
<ConfigList fileConfig={fileConfig} databaseConfig={databaseConfig} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import { transform, isEqual, isArray, isObject } from 'lodash';
|
||||
|
||||
/**
|
||||
* Find difference between two objects
|
||||
* @param {object} origObj - Source object to compare newObj against
|
||||
* @param {object} newObj - New object with potential changes
|
||||
* @return {object} differences
|
||||
*/
|
||||
const difference = (origObj, newObj) => {
|
||||
function changes(newObj, origObj) {
|
||||
let arrayIndexCounter = 0
|
||||
return transform(newObj, function (result, value, key) {
|
||||
if (!isEqual(value, origObj[key])) {
|
||||
let resultKey = isArray(origObj) ? arrayIndexCounter++ : key
|
||||
result[resultKey] = (isObject(value) && isObject(origObj[key])) ? changes(value, origObj[key]) : value
|
||||
}
|
||||
})
|
||||
}
|
||||
return changes(newObj, origObj)
|
||||
}
|
||||
|
||||
export default difference;
|
|
@ -13,7 +13,6 @@
|
|||
"react-diff-viewer": "^3.1.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-redux": "^7.2.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"redux": "^4.0.5",
|
||||
"redux-immutable": "^4.0.0",
|
||||
"redux-logger": "^3.0.6",
|
||||
|
|
Loading…
Reference in New Issue