diff --git a/.eslintrc b/.eslintrc index 6120fb2..dc830b3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -26,6 +26,14 @@ "strapi": true }, "rules": { + "import/no-unresolved": [2, { + "ignore": [ + "@strapi/strapi/admin", + "@strapi/icons/symbols", + "@strapi/admin/strapi-admin" + ] + }], + "template-curly-spacing" : "off", "indent" : "off", diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ef4d821..58b29b8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,6 +8,7 @@ on: branches: - master - develop + - beta jobs: lint: diff --git a/admin/src/components/ActionButtons/index.js b/admin/src/components/ActionButtons/index.jsx similarity index 84% rename from admin/src/components/ActionButtons/index.js rename to admin/src/components/ActionButtons/index.jsx index 55a183c..afe5cfc 100644 --- a/admin/src/components/ActionButtons/index.js +++ b/admin/src/components/ActionButtons/index.jsx @@ -4,15 +4,16 @@ import { useDispatch, useSelector } from 'react-redux'; import { isEmpty } from 'lodash'; import { Button } from '@strapi/design-system'; import { Map } from 'immutable'; -import { useNotification } from '@strapi/helper-plugin'; +import { getFetchClient, useNotification } from '@strapi/strapi/admin'; import { useIntl } from 'react-intl'; import ConfirmModal from '../ConfirmModal'; import { exportAllConfig, importAllConfig } from '../../state/actions/Config'; const ActionButtons = () => { + const { post, get } = getFetchClient(); const dispatch = useDispatch(); - const toggleNotification = useNotification(); + const { toggleNotification } = useNotification(); const [modalIsOpen, setModalIsOpen] = useState(false); const [actionType, setActionType] = useState(''); const partialDiff = useSelector((state) => state.getIn(['config', 'partialDiff'], Map({}))).toJS(); @@ -43,7 +44,7 @@ const ActionButtons = () => { isOpen={modalIsOpen} onClose={closeModal} type={actionType} - onSubmit={(force) => actionType === 'import' ? dispatch(importAllConfig(partialDiff, force, toggleNotification)) : dispatch(exportAllConfig(partialDiff, toggleNotification))} + onSubmit={(force) => actionType === 'import' ? dispatch(importAllConfig(partialDiff, force, toggleNotification, formatMessage, post, get)) : dispatch(exportAllConfig(partialDiff, toggleNotification, formatMessage, post, get))} /> ); diff --git a/admin/src/components/ConfigDiff/index.js b/admin/src/components/ConfigDiff/index.jsx similarity index 75% rename from admin/src/components/ConfigDiff/index.js rename to admin/src/components/ConfigDiff/index.jsx index d80db03..e5adb01 100644 --- a/admin/src/components/ConfigDiff/index.js +++ b/admin/src/components/ConfigDiff/index.jsx @@ -3,11 +3,8 @@ import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer-continued'; import { useIntl } from 'react-intl'; import { - ModalLayout, - ModalBody, - ModalHeader, + Modal, Grid, - GridItem, Typography, } from '@strapi/design-system'; @@ -16,32 +13,32 @@ const ConfigDiff = ({ isOpen, onClose, oldValue, newValue, configName }) => { if (!isOpen) return null; return ( - - + {formatMessage({ id: 'config-sync.ConfigDiff.Title' })} {configName} - - - - + + + + {formatMessage({ id: 'config-sync.ConfigDiff.SyncDirectory' })} - - + + {formatMessage({ id: 'config-sync.ConfigDiff.Database' })} - - + + - - + + ); }; diff --git a/admin/src/components/ConfigList/ConfigListRow/index.js b/admin/src/components/ConfigList/ConfigListRow/index.jsx similarity index 93% rename from admin/src/components/ConfigList/ConfigListRow/index.js rename to admin/src/components/ConfigList/ConfigListRow/index.jsx index 312cff5..96c7bd3 100644 --- a/admin/src/components/ConfigList/ConfigListRow/index.js +++ b/admin/src/components/ConfigList/ConfigListRow/index.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Tr, Td, BaseCheckbox } from '@strapi/design-system'; +import { Tr, Td, Checkbox } from '@strapi/design-system'; const CustomRow = ({ row, checked, updateValue }) => { const { configName, configType, state, onClick } = row; @@ -42,7 +42,7 @@ const CustomRow = ({ row, checked, updateValue }) => { style={{ cursor: 'pointer' }} > - { - setCheckedItems(checkedItems.map(() => value))} diff --git a/admin/src/components/ConfirmModal/index.js b/admin/src/components/ConfirmModal/index.jsx similarity index 89% rename from admin/src/components/ConfirmModal/index.js rename to admin/src/components/ConfirmModal/index.jsx index c26e842..162edcc 100644 --- a/admin/src/components/ConfirmModal/index.js +++ b/admin/src/components/ConfirmModal/index.jsx @@ -4,17 +4,14 @@ import { useSelector } from 'react-redux'; import { Dialog, - DialogBody, - DialogFooter, Flex, Typography, - Stack, Button, Checkbox, Divider, Box, } from '@strapi/design-system'; -import { ExclamationMarkCircle } from '@strapi/icons'; +import { WarningCircle } from '@strapi/icons'; const ConfirmModal = ({ isOpen, onClose, onSubmit, type }) => { const soft = useSelector((state) => state.getIn(['config', 'appEnv', 'config', 'soft'], false)); @@ -24,21 +21,21 @@ const ConfirmModal = ({ isOpen, onClose, onSubmit, type }) => { if (!isOpen) return null; return ( - - }> - + }> + {formatMessage({ id: `config-sync.popUpWarning.warning.${type}_1` })}
{formatMessage({ id: `config-sync.popUpWarning.warning.${type}_2` })}
-
-
+ + {(soft && type === 'import') && ( @@ -54,7 +51,7 @@ const ConfirmModal = ({ isOpen, onClose, onSubmit, type }) => { )} - { @@ -76,7 +73,7 @@ const ConfirmModal = ({ isOpen, onClose, onSubmit, type }) => { {formatMessage({ id: `config-sync.popUpWarning.button.${type}` })} )} /> -
+ ); }; diff --git a/admin/src/components/FirstExport/index.js b/admin/src/components/FirstExport/index.jsx similarity index 62% rename from admin/src/components/FirstExport/index.js rename to admin/src/components/FirstExport/index.jsx index 3fbbcc1..151ea35 100644 --- a/admin/src/components/FirstExport/index.js +++ b/admin/src/components/FirstExport/index.jsx @@ -1,14 +1,17 @@ import React, { useState } from 'react'; import { useIntl } from 'react-intl'; import { useDispatch } from 'react-redux'; -import { NoContent, useNotification } from '@strapi/helper-plugin'; -import { Button } from '@strapi/design-system'; +import { getFetchClient, useNotification } from '@strapi/strapi/admin'; +import { Button, EmptyStateLayout } from '@strapi/design-system'; +import { EmptyDocuments } from '@strapi/icons/symbols'; + import { exportAllConfig } from '../../state/actions/Config'; import ConfirmModal from '../ConfirmModal'; const FirstExport = () => { - const toggleNotification = useNotification(); + const { post, get } = getFetchClient(); + const { toggleNotification } = useNotification(); const dispatch = useDispatch(); const [modalIsOpen, setModalIsOpen] = useState(false); const { formatMessage } = useIntl(); @@ -19,15 +22,12 @@ const FirstExport = () => { isOpen={modalIsOpen} onClose={() => setModalIsOpen(false)} type="export" - onSubmit={() => dispatch(exportAllConfig([], toggleNotification))} + onSubmit={() => dispatch(exportAllConfig([], toggleNotification, formatMessage, post, get))} /> - setModalIsOpen(true)}>{formatMessage({ id: 'config-sync.FirstExport.Button' })}} + icon={} /> ); diff --git a/admin/src/components/Header/index.js b/admin/src/components/Header/index.jsx similarity index 78% rename from admin/src/components/Header/index.js rename to admin/src/components/Header/index.jsx index 4774b15..1fa3259 100644 --- a/admin/src/components/Header/index.js +++ b/admin/src/components/Header/index.jsx @@ -7,14 +7,15 @@ import React, { memo } from 'react'; import { useIntl } from 'react-intl'; -import { HeaderLayout, Box } from '@strapi/design-system'; +import { Layouts } from '@strapi/admin/strapi-admin'; +import { Box } from '@strapi/design-system'; const HeaderComponent = () => { const { formatMessage } = useIntl(); return ( - { - const { formatMessage } = useIntl(); - return ( - - ); -}; - -export default NoChanges; diff --git a/admin/src/components/NoChanges/index.jsx b/admin/src/components/NoChanges/index.jsx new file mode 100644 index 0000000..3b27e05 --- /dev/null +++ b/admin/src/components/NoChanges/index.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { EmptyStateLayout } from '@strapi/design-system'; +import { useIntl } from 'react-intl'; +import { EmptyDocuments } from '@strapi/icons/symbols'; + +const NoChanges = () => { + const { formatMessage } = useIntl(); + return ( + } + /> + ); +}; + +export default NoChanges; diff --git a/admin/src/containers/App/index.js b/admin/src/containers/App/index.jsx similarity index 78% rename from admin/src/containers/App/index.js rename to admin/src/containers/App/index.jsx index 26778c7..4d04208 100644 --- a/admin/src/containers/App/index.js +++ b/admin/src/containers/App/index.jsx @@ -7,7 +7,7 @@ import React from 'react'; import { Provider } from 'react-redux'; -import { CheckPagePermissions } from '@strapi/helper-plugin'; +import { Page } from '@strapi/strapi/admin'; import pluginPermissions from '../../permissions'; import Header from '../../components/Header'; @@ -16,12 +16,12 @@ import ConfigPage from '../ConfigPage'; const App = () => { return ( - +
- + ); }; diff --git a/admin/src/containers/ConfigPage/index.js b/admin/src/containers/ConfigPage/index.jsx similarity index 72% rename from admin/src/containers/ConfigPage/index.js rename to admin/src/containers/ConfigPage/index.jsx index 5dee8db..0d8bab9 100644 --- a/admin/src/containers/ConfigPage/index.js +++ b/admin/src/containers/ConfigPage/index.jsx @@ -3,30 +3,34 @@ import { useDispatch, useSelector } from 'react-redux'; import { Map } from 'immutable'; import { Box, - ContentLayout, Alert, Typography, } from '@strapi/design-system'; -import { useNotification } from '@strapi/helper-plugin'; +import { useNotification } from '@strapi/strapi/admin'; +import { getFetchClient, Layouts } from '@strapi/admin/strapi-admin'; +import { useIntl } from 'react-intl'; import { getAllConfigDiff, getAppEnv } from '../../state/actions/Config'; import ConfigList from '../../components/ConfigList'; import ActionButtons from '../../components/ActionButtons'; const ConfigPage = () => { - const toggleNotification = useNotification(); + const { toggleNotification } = useNotification(); + const { get } = getFetchClient(); + const { formatMessage } = useIntl(); + const dispatch = useDispatch(); const isLoading = useSelector((state) => state.getIn(['config', 'isLoading'], Map({}))); const configDiff = useSelector((state) => state.getIn(['config', 'configDiff'], Map({}))); const appEnv = useSelector((state) => state.getIn(['config', 'appEnv', 'env'])); useEffect(() => { - dispatch(getAllConfigDiff(toggleNotification)); - dispatch(getAppEnv(toggleNotification)); + dispatch(getAllConfigDiff(toggleNotification, formatMessage, get)); + dispatch(getAppEnv(toggleNotification, formatMessage, get)); }, []); return ( - + {appEnv === 'production' && ( @@ -38,7 +42,7 @@ const ConfigPage = () => { )} - + ); }; diff --git a/admin/src/containers/Initializer/index.js b/admin/src/containers/Initializer/index.jsx similarity index 100% rename from admin/src/containers/Initializer/index.js rename to admin/src/containers/Initializer/index.jsx diff --git a/admin/src/helpers/pluginId.js b/admin/src/helpers/pluginId.js index 4a3a03f..99dcc2f 100644 --- a/admin/src/helpers/pluginId.js +++ b/admin/src/helpers/pluginId.js @@ -1,8 +1,8 @@ -const pluginPkg = require('../../../package.json'); +import pluginPkg from '../../../package.json'; const pluginId = pluginPkg.name.replace( /^strapi-plugin-/i, '', ); -module.exports = pluginId; +export default pluginId; diff --git a/admin/src/helpers/prefixPluginTranslations.js b/admin/src/helpers/prefixPluginTranslations.js new file mode 100644 index 0000000..b7b93b2 --- /dev/null +++ b/admin/src/helpers/prefixPluginTranslations.js @@ -0,0 +1,11 @@ +const prefixPluginTranslations = (trad, pluginId) => { + if (!pluginId) { + throw new TypeError("pluginId can't be empty"); + } + return Object.keys(trad).reduce((acc, current) => { + acc[`${pluginId}.${current}`] = trad[current]; + return acc; + }, {}); +}; + +export { prefixPluginTranslations }; diff --git a/admin/src/index.js b/admin/src/index.js index ea10556..d3756ff 100644 --- a/admin/src/index.js +++ b/admin/src/index.js @@ -1,6 +1,6 @@ -import { prefixPluginTranslations } from '@strapi/helper-plugin'; import pluginPkg from '../../package.json'; import pluginId from './helpers/pluginId'; +import { prefixPluginTranslations } from './helpers/prefixPluginTranslations'; import pluginPermissions from './permissions'; // import pluginIcon from './components/PluginIcon'; // import getTrad from './helpers/getTrad'; diff --git a/admin/src/state/actions/Config.js b/admin/src/state/actions/Config.js index 5922bfe..ef1115e 100644 --- a/admin/src/state/actions/Config.js +++ b/admin/src/state/actions/Config.js @@ -4,18 +4,16 @@ * */ -import { request } from '@strapi/helper-plugin'; - -export function getAllConfigDiff(toggleNotification) { +export function getAllConfigDiff(toggleNotification, formatMessage, get) { return async function(dispatch) { dispatch(setLoadingState(true)); try { - const configDiff = await request('/config-sync/diff', { method: 'GET' }); + const configDiff = await get('/config-sync/diff'); dispatch(setConfigPartialDiffInState([])); - dispatch(setConfigDiffInState(configDiff)); + dispatch(setConfigDiffInState(configDiff.data)); dispatch(setLoadingState(false)); } catch (err) { - toggleNotification({ type: 'warning', message: { id: 'notification.error' } }); + toggleNotification({ type: 'warning', message: formatMessage({ id: 'notification.error' }) }); dispatch(setLoadingState(false)); } }; @@ -37,40 +35,34 @@ export function setConfigPartialDiffInState(config) { }; } -export function exportAllConfig(partialDiff, toggleNotification) { +export function exportAllConfig(partialDiff, toggleNotification, formatMessage, post, get) { return async function(dispatch) { dispatch(setLoadingState(true)); try { - const { message } = await request('/config-sync/export', { - method: 'POST', - body: partialDiff, - }); - toggleNotification({ type: 'success', message }); - dispatch(getAllConfigDiff(toggleNotification)); + const response = await post('/config-sync/export', partialDiff); + toggleNotification({ type: 'success', message: response.data.message }); + dispatch(getAllConfigDiff(toggleNotification, formatMessage, get)); dispatch(setLoadingState(false)); } catch (err) { - toggleNotification({ type: 'warning', message: { id: 'notification.error' } }); + toggleNotification({ type: 'warning', message: formatMessage({ id: 'notification.error' }) }); dispatch(setLoadingState(false)); } }; } -export function importAllConfig(partialDiff, force, toggleNotification) { +export function importAllConfig(partialDiff, force, toggleNotification, formatMessage, post, get) { return async function(dispatch) { dispatch(setLoadingState(true)); try { - const { message } = await request('/config-sync/import', { - method: 'POST', - body: { - force, - config: partialDiff, - }, + const response = await post('/config-sync/import', { + force, + config: partialDiff, }); - toggleNotification({ type: 'success', message }); - dispatch(getAllConfigDiff(toggleNotification)); + toggleNotification({ type: 'success', message: response.data.message }); + dispatch(getAllConfigDiff(toggleNotification, formatMessage, get)); dispatch(setLoadingState(false)); } catch (err) { - toggleNotification({ type: 'warning', message: { id: 'notification.error' } }); + toggleNotification({ type: 'warning', message: formatMessage({ id: 'notification.error' }) }); dispatch(setLoadingState(false)); } }; @@ -84,15 +76,13 @@ export function setLoadingState(value) { }; } -export function getAppEnv(toggleNotification) { +export function getAppEnv(toggleNotification, formatMessage, get) { return async function(dispatch) { try { - const envVars = await request('/config-sync/app-env', { - method: 'GET', - }); - dispatch(setAppEnvInState(envVars)); + const envVars = await get('/config-sync/app-env'); + dispatch(setAppEnvInState(envVars.data)); } catch (err) { - toggleNotification({ type: 'warning', message: { id: 'notification.error' } }); + toggleNotification({ type: 'warning', message: formatMessage({ id: 'notification.error' }) }); } }; } diff --git a/package.json b/package.json index 8161410..62f761f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-config-sync", - "version": "1.2.5", + "version": "2.0.0-beta.4", "description": "Migrate your config data across environments using the CLI or Strapi admin panel.", "strapi": { "displayName": "Config Sync", @@ -31,6 +31,7 @@ "immutable": "^3.8.2", "inquirer": "^8.2.0", "react-diff-viewer-continued": "3.2.6", + "react-intl": "6.6.2", "redux-immutable": "^4.0.0", "redux-thunk": "^2.3.0" }, @@ -54,13 +55,13 @@ "strapi-server.js" ], "peerDependencies": { - "@strapi/strapi": "^4.0.0" + "@strapi/strapi": "^5.0.0-rc.2" }, "devDependencies": { - "@strapi/design-system": "^1.14.1", - "@strapi/helper-plugin": "^4.19.0", - "@strapi/icons": "^1.14.1", - "@strapi/utils": "^4.19.0", + "@strapi/design-system": "2.0.0-rc.7", + "@strapi/icons": "2.0.0-rc.7", + "@strapi/strapi": "5.0.0-rc.2", + "@strapi/utils": "5.0.0-rc.2", "babel-eslint": "9.0.0", "eslint": "^7.32.0", "eslint-config-airbnb": "^18.2.1", @@ -78,7 +79,6 @@ "jest-styled-components": "^7.0.2", "lodash": "^4.17.11", "react": "^17.0.2", - "react-intl": "^5.20.12", "react-redux": "^7.2.2", "redux": "^4.0.5", "styled-components": "^5.2.3" diff --git a/playground/.env b/playground/.env index 57cb1e7..3dff915 100644 --- a/playground/.env +++ b/playground/.env @@ -1,7 +1,10 @@ HOST=0.0.0.0 PORT=1337 -APP_KEYS=SIwLyqu+IpSHIuUBDQfPZg==,Nzqbq2C3ATsR19u5XEAJQA==,/Agk5Sn8M4EzfoSiIHcDlQ==,gSxT2T0k2zbQatKXUV0zCA== -API_TOKEN_SALT=reQcUBbGXD2KWG2QpRn7DA== -ADMIN_JWT_SECRET= 69mzgwRGfEBUhPEaas8EBA== -TRANSFER_TOKEN_SALT=/LTsSGpC5afHICjZu0oEuQ== -JWT_SECRET=E0TTVdsr+M/FXAjfrNIgXA== +APP_KEYS=ujfpKPEst1tv0WDxJEhjJw==,MOnFjWYKbWYmtrBZ3cQTFQ==,zQpX70tJw/Mw+Y656kXfVA==,xJT1vbsiz3cgabfgpLu72w== +API_TOKEN_SALT=5FoJkYoZV8IA6+NnZJDzng== +ADMIN_JWT_SECRET=tkeg3+HqE+QmTd2ITEivtA== +TRANSFER_TOKEN_SALT=UUMCRQ2cx9qvKw/RkB815Q== +# Database +DATABASE_CLIENT=sqlite +DATABASE_FILENAME=.tmp/data.db +JWT_SECRET=Dn/nUGQsREUw4/lfQYOScw== diff --git a/playground/.env.example b/playground/.env.example index b667b6c..ebfc96a 100644 --- a/playground/.env.example +++ b/playground/.env.example @@ -1,2 +1,7 @@ HOST=0.0.0.0 PORT=1337 +APP_KEYS="toBeModified1,toBeModified2" +API_TOKEN_SALT=tobemodified +ADMIN_JWT_SECRET=tobemodified +TRANSFER_TOKEN_SALT=tobemodified +JWT_SECRET=tobemodified diff --git a/playground/.strapi/client/app.js b/playground/.strapi/client/app.js index 1996af5..ff2a975 100644 --- a/playground/.strapi/client/app.js +++ b/playground/.strapi/client/app.js @@ -2,15 +2,15 @@ * This file was automatically generated by Strapi. * Any modifications made will be discarded. */ -import i18N from "@strapi/plugin-i18n/strapi-admin"; import usersPermissions from "@strapi/plugin-users-permissions/strapi-admin"; +import strapiCloud from "@strapi/plugin-cloud/strapi-admin"; import configSync from "strapi-plugin-config-sync/strapi-admin"; import { renderAdmin } from "@strapi/strapi/admin"; renderAdmin(document.getElementById("strapi"), { plugins: { - i18n: i18N, "users-permissions": usersPermissions, + "strapi-cloud": strapiCloud, "config-sync": configSync, }, }); diff --git a/playground/.strapi/client/index.html b/playground/.strapi/client/index.html index 08d9c27..4e9d27c 100644 --- a/playground/.strapi/client/index.html +++ b/playground/.strapi/client/index.html @@ -1,4 +1,4 @@ - +