Finalize main frontend functionality

pull/1/head
Boaz Poolman 2021-03-20 16:51:34 +01:00
parent 074224f56f
commit ba95ed0e2d
8 changed files with 125 additions and 47 deletions

View File

@ -1,12 +1,35 @@
import React from 'react'; import React, { useState } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { useDispatch } from 'react-redux';
import { Button } from '@buffetjs/core'; import { Button } from '@buffetjs/core';
import ConfirmModal from '../ConfirmModal';
import { exportAllConfig, importAllConfig } from '../../state/actions/Config';
const ActionButtons = ({ diff }) => {
const dispatch = useDispatch();
const [modalIsOpen, setModalIsOpen] = useState(false);
const [actionType, setActionType] = useState('');
const closeModal = () => {
setActionType('');
setModalIsOpen(false);
};
const openModal = (type) => {
setActionType(type);
setModalIsOpen(true);
};
const ActionButtons = () => {
return ( return (
<ActionButtonsStyling> <ActionButtonsStyling>
<Button color="primary" label="Import"/> <Button disabled={!diff} color="primary" label="Import" onClick={() => openModal('import')} />
<Button color="primary" label="Export"/> <Button disabled={!diff} color="primary" label="Export" onClick={() => openModal('export')} />
<ConfirmModal
isOpen={modalIsOpen}
onClose={closeModal}
type={actionType}
onSubmit={() => actionType === 'import' ? dispatch(importAllConfig()) : dispatch(exportAllConfig())}
/>
</ActionButtonsStyling> </ActionButtonsStyling>
); );
} }

View File

@ -1,20 +1,15 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Table } from '@buffetjs/core'; import { Table } from '@buffetjs/core';
import difference from '../../helpers/getObjectDiff';
import ConfigDiff from '../ConfigDiff'; import ConfigDiff from '../ConfigDiff';
const headers = [ const headers = [
{
name: 'Id',
value: 'id',
},
{ {
name: 'Config name', name: 'Config name',
value: 'name', value: 'config_name',
}, },
{ {
name: 'Database table', name: 'Database table',
value: 'lastname', value: 'table_name',
}, },
{ {
name: 'Change', name: 'Change',
@ -22,15 +17,21 @@ const headers = [
}, },
]; ];
const ConfigList = ({ fileConfig, databaseConfig }) => { const ConfigList = ({ fileConfig, databaseConfig, isLoading, diff }) => {
const diff = difference(fileConfig.toJS(), databaseConfig.toJS());
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const [originalConfig, setOriginalConfig] = useState({}); const [originalConfig, setOriginalConfig] = useState({});
const [newConfig, setNewConfig] = useState({}); const [newConfig, setNewConfig] = useState({});
const [configName, setConfigName] = useState(''); const [configName, setConfigName] = useState('');
let rows = []; let rows = [];
Object.keys(diff).map((config) => rows.push({ name: config })); Object.keys(diff).map((config) => {
// @TODO implement different config types, roles/permissions e.g.
rows.push({
config_name: config,
table_name: 'core_store',
change_type: ''
});
});
const closeModal = () => { const closeModal = () => {
setOriginalConfig({}); setOriginalConfig({});
@ -49,15 +50,17 @@ const ConfigList = ({ fileConfig, databaseConfig }) => {
onToggle={closeModal} onToggle={closeModal}
configName={configName} configName={configName}
/> />
<Table <Table
headers={headers} headers={headers}
onClickRow={(e, data) => { onClickRow={(e, data) => {
setOriginalConfig(fileConfig.get(data.name)); setOriginalConfig(fileConfig.get(data.config_name));
setNewConfig(databaseConfig.get(data.name)); setNewConfig(databaseConfig.get(data.config_name));
setConfigName(data.name); setConfigName(data.config_name);
setOpenModal(true); setOpenModal(true);
}} }}
rows={rows} rows={!isLoading ? rows : []}
tableEmptyText="No config changes. You are up to date!"
isLoading={isLoading}
/> />
</div> </div>
); );

View File

@ -0,0 +1,34 @@
import React from 'react';
import {
ModalConfirm,
} from 'strapi-helper-plugin';
import getTrad from '../../helpers/getTrad';
const ConfirmModal = ({ isOpen, onClose, onSubmit, type }) => {
return (
<ModalConfirm
confirmButtonLabel={{
id: getTrad(`popUpWarning.button.${type}`),
}}
isOpen={isOpen}
toggle={onClose}
onClosed={onClose}
onConfirm={() => {
onClose();
onSubmit();
}}
type="success"
content={{
id: getTrad(`popUpWarning.warning.${type}`),
values: {
br: () => <br />,
},
}}
>
<div>Zeker?</div>
</ModalConfirm>
);
}
export default ConfirmModal;

View File

@ -1,22 +0,0 @@
/*
*
* HeaderComponent
*
*/
import React, { memo } from 'react';
import { Header } from '@buffetjs/custom';
import { useGlobalContext } from 'strapi-helper-plugin';
const HeaderComponent = (props) => {
const globalContext = useGlobalContext();
return (
<Header
title={{ label: 'Config Sync' }}
content="Manage your database config across environments."
/>
);
};
export default memo(HeaderComponent);

View File

@ -1,29 +1,30 @@
import React, { useEffect } from 'react'; import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Map } from 'immutable'; import { Map } from 'immutable';
import { getAllDatabaseConfig, getAllFileConfig } from '../../state/actions/Config'; import { getAllDatabaseConfig, getAllFileConfig } from '../../state/actions/Config';
import ConfigList from '../../components/ConfigList'; import ConfigList from '../../components/ConfigList';
import ActionButtons from '../../components/ActionButtons'; import ActionButtons from '../../components/ActionButtons';
import difference from '../../helpers/getObjectDiff';
const ConfigPage = () => { const ConfigPage = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [isLoading, setIsLoading] = useState(true);
const fileConfig = useSelector((state) => state.getIn(['config', 'fileConfig']), Map()); const fileConfig = useSelector((state) => state.getIn(['config', 'fileConfig']), Map());
const databaseConfig = useSelector((state) => state.getIn(['config', 'databaseConfig']), Map()); const databaseConfig = useSelector((state) => state.getIn(['config', 'databaseConfig']), Map());
useEffect(() => { useEffect(() => {
dispatch(getAllDatabaseConfig()); dispatch(getAllDatabaseConfig());
dispatch(getAllFileConfig()); dispatch(getAllFileConfig());
setIsLoading(false);
}, []); }, []);
if (fileConfig.size === 0 || databaseConfig.size === 0) { const diff = difference(fileConfig.toJS(), databaseConfig.toJS());
return null;
}
return ( return (
<div> <div>
<ActionButtons /> <ActionButtons diff={diff} />
<ConfigList fileConfig={fileConfig} databaseConfig={databaseConfig} /> <ConfigList fileConfig={fileConfig} databaseConfig={databaseConfig} isLoading={isLoading} diff={diff} />
</div> </div>
); );
} }

View File

@ -0,0 +1,5 @@
import pluginId from './pluginId';
const getTrad = id => `${pluginId}.${id}`;
export default getTrad;

View File

@ -49,4 +49,34 @@ export function setFileConfigInState(config) {
type: SET_FILE_CONFIG_IN_STATE, type: SET_FILE_CONFIG_IN_STATE,
config, config,
}; };
}
export function exportAllConfig() {
return async function(dispatch) {
try {
const { message } = await request('/config/export', { method: 'GET' });
dispatch(getAllFileConfig());
dispatch(getAllDatabaseConfig());
strapi.notification.success(message);
} catch(err) {
console.log(err);
strapi.notification.error('notification.error');
}
}
}
export function importAllConfig() {
return async function(dispatch) {
try {
const { message } = await request('/config/import', { method: 'GET' });
dispatch(getAllFileConfig());
dispatch(getAllDatabaseConfig());
strapi.notification.success(message);
} catch(err) {
console.log(err);
strapi.notification.error('notification.error');
}
}
} }

View File

@ -1,3 +1,7 @@
{ {
"popUpWarning.warning.import": "If you continue all your local config files<br></br>will be imported into the database.",
"popUpWarning.warning.export": "If you continue all your database config<br></br>will be written into config files.",
"popUpWarning.button.import": "Yes, import",
"popUpWarning.button.export": "Yes, export",
"plugin.name": "Config Sync" "plugin.name": "Config Sync"
} }