Преглед изворни кода

Merge pull request #4537 from weseek/feat/pt-v4-compatible-env

feat: added a page schema compatibility section to admin page
Yuki Takei пре 4 година
родитељ
комит
ab205aa568

+ 9 - 0
packages/app/src/client/services/AdminAppContainer.js

@@ -22,6 +22,7 @@ export default class AdminAppContainer extends Container {
       isEmailPublishedForNewUser: true,
       isEmailPublishedForNewUser: true,
       fileUpload: '',
       fileUpload: '',
 
 
+      isV5Compatible: null,
       siteUrl: '',
       siteUrl: '',
       envSiteUrl: '',
       envSiteUrl: '',
       isSetSiteUrl: true,
       isSetSiteUrl: true,
@@ -81,6 +82,7 @@ export default class AdminAppContainer extends Container {
       globalLang: appSettingsParams.globalLang,
       globalLang: appSettingsParams.globalLang,
       isEmailPublishedForNewUser: appSettingsParams.isEmailPublishedForNewUser,
       isEmailPublishedForNewUser: appSettingsParams.isEmailPublishedForNewUser,
       fileUpload: appSettingsParams.fileUpload,
       fileUpload: appSettingsParams.fileUpload,
+      isV5Compatible: appSettingsParams.isV5Compatible,
       siteUrl: appSettingsParams.siteUrl,
       siteUrl: appSettingsParams.siteUrl,
       envSiteUrl: appSettingsParams.envSiteUrl,
       envSiteUrl: appSettingsParams.envSiteUrl,
       isSetSiteUrl: !!appSettingsParams.siteUrl,
       isSetSiteUrl: !!appSettingsParams.siteUrl,
@@ -160,6 +162,13 @@ export default class AdminAppContainer extends Container {
     this.setState({ fileUpload });
     this.setState({ fileUpload });
   }
   }
 
 
+  /**
+   * Change site url
+   */
+  changeisV5Compatible(isV5Compatible) {
+    this.setState({ isV5Compatible });
+  }
+
   /**
   /**
    * Change site url
    * Change site url
    */
    */

+ 21 - 2
packages/app/src/components/Admin/AdminHome/AdminHome.jsx

@@ -10,6 +10,7 @@ import { toastError } from '~/client/util/apiNotification';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import AppContainer from '~/client/services/AppContainer';
 import AppContainer from '~/client/services/AppContainer';
 import AdminHomeContainer from '~/client/services/AdminHomeContainer';
 import AdminHomeContainer from '~/client/services/AdminHomeContainer';
+import AdminAppContainer from '~/client/services/AdminAppContainer';
 import SystemInfomationTable from './SystemInfomationTable';
 import SystemInfomationTable from './SystemInfomationTable';
 import InstalledPluginTable from './InstalledPluginTable';
 import InstalledPluginTable from './InstalledPluginTable';
 import EnvVarsTable from './EnvVarsTable';
 import EnvVarsTable from './EnvVarsTable';
@@ -32,10 +33,27 @@ class AdminHome extends React.Component {
   }
   }
 
 
   render() {
   render() {
-    const { t, adminHomeContainer } = this.props;
+    const { t, adminHomeContainer, adminAppContainer } = this.props;
+    const { isV5Compatible } = adminAppContainer.state;
+
+    let alertStyle = 'alert-info';
+    if (isV5Compatible == null) alertStyle = 'alert-warning';
 
 
     return (
     return (
       <Fragment>
       <Fragment>
+        {
+          // not show if true
+          !isV5Compatible
+          && (
+            <div className={`alert ${alertStyle}`}>
+              GROWI is running with v4 compatible pages. To use new features such as Page tree or easy renaming, please migrate page schema to v5.<br />
+              <a className="btn-link" href="/admin/app" rel="noopener noreferrer">
+                <i className="fa fa-link ml-1" aria-hidden="true"></i>
+                <strong>Upgrade to v5</strong>
+              </a>
+            </div>
+          )
+        }
         <p>
         <p>
           {t('admin:admin_top.wiki_administrator')}
           {t('admin:admin_top.wiki_administrator')}
           <br></br>
           <br></br>
@@ -97,12 +115,13 @@ class AdminHome extends React.Component {
 
 
 }
 }
 
 
-const AdminHomeWrapper = withUnstatedContainers(AdminHome, [AppContainer, AdminHomeContainer]);
+const AdminHomeWrapper = withUnstatedContainers(AdminHome, [AppContainer, AdminHomeContainer, AdminAppContainer]);
 
 
 AdminHome.propTypes = {
 AdminHome.propTypes = {
   t: PropTypes.func.isRequired, // i18next
   t: PropTypes.func.isRequired, // i18next
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   adminHomeContainer: PropTypes.instanceOf(AdminHomeContainer).isRequired,
   adminHomeContainer: PropTypes.instanceOf(AdminHomeContainer).isRequired,
+  adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
 };
 };
 
 
 export default withTranslation()(AdminHomeWrapper);
 export default withTranslation()(AdminHomeWrapper);

+ 25 - 2
packages/app/src/components/Admin/App/AppSettingsPageContents.jsx

@@ -2,19 +2,36 @@ import React, { Fragment } from 'react';
 import { withTranslation } from 'react-i18next';
 import { withTranslation } from 'react-i18next';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
+import { withUnstatedContainers } from '../../UnstatedUtils';
 import AppSetting from './AppSetting';
 import AppSetting from './AppSetting';
 import SiteUrlSetting from './SiteUrlSetting';
 import SiteUrlSetting from './SiteUrlSetting';
 import MailSetting from './MailSetting';
 import MailSetting from './MailSetting';
 import PluginSetting from './PluginSetting';
 import PluginSetting from './PluginSetting';
 import FileUploadSetting from './FileUploadSetting';
 import FileUploadSetting from './FileUploadSetting';
+import { V5PageMigration } from './V5PageMigration';
+
+import AdminAppContainer from '~/client/services/AdminAppContainer';
 
 
 class AppSettingsPageContents extends React.Component {
 class AppSettingsPageContents extends React.Component {
 
 
   render() {
   render() {
-    const { t } = this.props;
+    const { t, adminAppContainer } = this.props;
+    const { isV5Compatible } = adminAppContainer.state;
 
 
     return (
     return (
       <Fragment>
       <Fragment>
+        {
+          !isV5Compatible
+          && (
+            <div className="row">
+              <div className="col-lg-12">
+                <h2 className="admin-setting-header">V5 Page Migration</h2>
+                <V5PageMigration isV5Compatible={isV5Compatible} />
+              </div>
+            </div>
+          )
+        }
+
         <div className="row">
         <div className="row">
           <div className="col-lg-12">
           <div className="col-lg-12">
             <h2 className="admin-setting-header">{t('App Settings')}</h2>
             <h2 className="admin-setting-header">{t('App Settings')}</h2>
@@ -55,8 +72,14 @@ class AppSettingsPageContents extends React.Component {
 
 
 }
 }
 
 
+/**
+ * Wrapper component for using unstated
+ */
+const AppSettingsPageContentsWrapper = withUnstatedContainers(AppSettingsPageContents, [AdminAppContainer]);
+
 AppSettingsPageContents.propTypes = {
 AppSettingsPageContents.propTypes = {
   t: PropTypes.func.isRequired, // i18next
   t: PropTypes.func.isRequired, // i18next
+  adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
 };
 };
 
 
-export default withTranslation()(AppSettingsPageContents);
+export default withTranslation()(AppSettingsPageContentsWrapper);

+ 36 - 0
packages/app/src/components/Admin/App/V5PageMigration.tsx

@@ -0,0 +1,36 @@
+import React, { FC } from 'react';
+import PropTypes from 'prop-types';
+import { withTranslation } from 'react-i18next';
+
+
+export const V5PageMigration: FC<any> = (props) => {
+  const { t, isV5Compatible } = props;
+
+  return (
+    <>
+      <p className="card well">
+        GROWI is running with v4 compatible pages.<br />
+        To use new features such as Page tree or easy renaming, please migrate page schema to v5.<br />
+        <br />
+        <span className="text-danger">
+          <i className="icon-exclamation icon-fw"></i>
+          Note: You will lose unique constraint from page path.
+        </span>
+      </p>
+      <div className="row my-3">
+        <div className="mx-auto">
+          {
+            isV5Compatible == null
+            && (<button type="button" className="btn btn-secondary mr-3" onClick={() => { /* Set false */ }}>Not now</button>)
+          }
+          <button type="button" className="btn btn-warning" onClick={() => { /* Show modal, then start migration */ }}>Upgrade to v5</button>
+        </div>
+      </div>
+    </>
+  );
+};
+
+V5PageMigration.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+  isV5Compatible: PropTypes.bool,
+};

+ 1 - 0
packages/app/src/server/models/config.ts

@@ -36,6 +36,7 @@ export const generateConfigsForInstalling = (): { [key: string]: any } => {
   config['app:installed'] = true;
   config['app:installed'] = true;
   config['app:fileUpload'] = true;
   config['app:fileUpload'] = true;
   config['customize:isSavedStatesOfTabChanges'] = false;
   config['customize:isSavedStatesOfTabChanges'] = false;
+  config['app:isV5Compatible'] = true;
 
 
   return config;
   return config;
 };
 };

+ 1 - 0
packages/app/src/server/routes/apiv3/app-settings.js

@@ -225,6 +225,7 @@ module.exports = (crowi) => {
       globalLang: crowi.configManager.getConfig('crowi', 'app:globalLang'),
       globalLang: crowi.configManager.getConfig('crowi', 'app:globalLang'),
       isEmailPublishedForNewUser: crowi.configManager.getConfig('crowi', 'customize:isEmailPublishedForNewUser'),
       isEmailPublishedForNewUser: crowi.configManager.getConfig('crowi', 'customize:isEmailPublishedForNewUser'),
       fileUpload: crowi.configManager.getConfig('crowi', 'app:fileUpload'),
       fileUpload: crowi.configManager.getConfig('crowi', 'app:fileUpload'),
+      isV5Compatible: crowi.configManager.getConfig('crowi', 'app:isV5Compatible'),
       siteUrl: crowi.configManager.getConfig('crowi', 'app:siteUrl'),
       siteUrl: crowi.configManager.getConfig('crowi', 'app:siteUrl'),
       envSiteUrl: crowi.configManager.getConfigFromEnvVars('crowi', 'app:siteUrl'),
       envSiteUrl: crowi.configManager.getConfigFromEnvVars('crowi', 'app:siteUrl'),
       isMailerSetup: crowi.mailService.isMailerSetup,
       isMailerSetup: crowi.mailService.isMailerSetup,

+ 6 - 0
packages/app/src/server/service/config-loader.ts

@@ -172,6 +172,12 @@ const ENV_VAR_NAME_TO_CONFIG_INFO = {
     type:    ValueType.BOOLEAN,
     type:    ValueType.BOOLEAN,
     default: false,
     default: false,
   },
   },
+  IS_V5_COMPATIBLE: {
+    ns:      'crowi',
+    key:     'app:isV5Compatible',
+    type:    ValueType.BOOLEAN,
+    default: undefined,
+  },
   S2SMSG_PUBSUB_SERVER_TYPE: {
   S2SMSG_PUBSUB_SERVER_TYPE: {
     ns:      'crowi',
     ns:      'crowi',
     key:     's2sMessagingPubsub:serverType',
     key:     's2sMessagingPubsub:serverType',