Просмотр исходного кода

Merge commit 'a5bd4fb4c5dd95a74ee034706478b5119d45ce61' into feat/use-MongoDB-GridFS-for-file-storage

yusueketk 7 лет назад
Родитель
Сommit
ce9dba31cf

+ 11 - 1
CHANGES.md

@@ -1,10 +1,20 @@
 CHANGES
 ========
 
-## 3.2.8-RC
+## 3.2.9-RC
 
 * 
 
+## 3.2.8
+
+* Improvement: Add an option to use email for account link when using SAML federation
+* Fix: Editor layout is sometimes broken
+* Fix: Normalize table data for Spreadsheet like GUI (Handsontable) when import
+* Support: Improve development environment
+* Support: Upgrade libs
+    * googleapis
+    * react-dropzone
+
 ## 3.2.7
 
 * Feature: Import CSV/TSV/HTML table on Spreadsheet like GUI (Handsontable)

+ 1 - 0
config/webpack.common.js

@@ -20,6 +20,7 @@ module.exports = (options) => {
     mode: options.mode,
     entry: Object.assign({
       'js/app':                       './src/client/js/app',
+      'js/installer':                 './src/client/js/installer',
       'js/legacy':                    './src/client/js/legacy/crowi',
       'js/legacy-admin':              './src/client/js/legacy/crowi-admin',
       'js/legacy-presentation':       './src/client/js/legacy/crowi-presentation',

+ 0 - 0
config/webpack.dll.js → config/webpack.dev.dll.js


+ 4 - 4
package.json

@@ -1,6 +1,6 @@
 {
   "name": "growi",
-  "version": "3.2.8-RC",
+  "version": "3.2.9-RC",
   "description": "Team collaboration software using markdown",
   "tags": [
     "wiki",
@@ -24,7 +24,7 @@
     "build:dev:app:analyze": "cross-env ANALYZE=1 npm run build:dev:app:watch -- --profile",
     "build:dev:app:watch": "npm run build:dev:app -- --watch",
     "build:dev:app": "npm run clean:app && env-cmd config/env.dev.js webpack --config config/webpack.dev.js --progress",
-    "build:dev:dll": "webpack --config config/webpack.dll.js",
+    "build:dev:dll": "webpack --config config/webpack.dev.dll.js",
     "build:dev:watch": "npm-run-all -s build:dev:dll build:dev:app:watch",
     "build:dev": "npm-run-all -s build:dev:dll build:dev:app",
     "build:prod:analyze": "cross-env ANALYZE=1 npm run build:prod",
@@ -85,7 +85,7 @@
     "express-sanitizer": "^1.0.4",
     "express-session": "~1.15.0",
     "express-webpack-assets": "^0.1.0",
-    "googleapis": "^34.0.0",
+    "googleapis": "^35.0.0",
     "graceful-fs": "^4.1.11",
     "growi-pluginkit": "^1.1.0",
     "helmet": "^3.13.0",
@@ -190,7 +190,7 @@
     "react-clipboard.js": "^2.0.0",
     "react-codemirror2": "^5.0.4",
     "react-dom": "^16.4.1",
-    "react-dropzone": "^6.0.2",
+    "react-dropzone": "^7.0.1",
     "react-frame-component": "^4.0.0",
     "react-i18next": "=7.13.0",
     "reveal.js": "^3.5.0",

+ 7 - 0
resource/locales/ja/translation.json

@@ -118,6 +118,13 @@
   "Deleted Pages": "削除済みページ",
   "Sign out": "ログアウト",
 
+  "installer": {
+    "setup": "セットアップ",
+    "create_initial_account": "最初のアカウントの作成",
+    "initial_account_will_be_administrator_automatically": "初めに作成するアカウントは、自動的に管理者権限が付与されます",
+    "unavaliable_user_id": "このユーザーIDは利用できません。"
+  },
+
   "page_register": {
     "notice": {
        "restricted": "この Wiki への新規登録は制限されています。",

+ 61 - 0
src/client/js/components/InstallerForm.js

@@ -0,0 +1,61 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { translate } from 'react-i18next';
+
+class InstallerForm extends React.Component {
+  render() {
+    return (
+      <form role="form" action="/installer/createAdmin" method="post" id="register-form">
+        <div className="input-group" id="input-group-username">
+          <span className="input-group-addon"><i className="icon-user"></i></span>
+          <input type="text" className="form-control" placeholder={ this.props.t('User ID') }
+            name="registerForm[username]" defaultValue={this.props.userName} required />
+        </div>
+        <p className="help-block">
+          <span id="help-block-username"></span>
+        </p>
+
+        <div className="input-group">
+          <span className="input-group-addon"><i className="icon-tag"></i></span>
+          <input type="text" className="form-control" placeholder={ this.props.t('Name') } name="registerForm[name]" defaultValue={ this.props.name } required />
+        </div>
+
+        <div className="input-group">
+          <span className="input-group-addon"><i className="icon-envelope"></i></span>
+          <input type="email" className="form-control" placeholder={ this.props.t('Email') } name="registerForm[email]" defaultValue={ this.props.email } required />
+        </div>
+
+        <div className="input-group">
+          <span className="input-group-addon"><i className="icon-lock"></i></span>
+          <input type="password" className="form-control" placeholder={ this.props.t('Password') } name="registerForm[password]" required />
+        </div>
+
+        <input type="hidden" name="_csrf" value={ this.props.csrf } />
+        <div className="input-group m-t-30 m-b-20 d-flex justify-content-center">
+          <button type="submit" className="fcbtn btn btn-success btn-1b btn-register">
+            <span className="btn-label"><i className="icon-user-follow"></i></span>
+            { this.props.t('Create') }
+          </button>
+        </div>
+
+        <div className="input-group m-t-30 d-flex justify-content-center">
+          <a href="https://growi.org" className="link-growi-org">
+            <span className="growi">GROWI</span>.<span className="org">ORG</span>
+          </a>
+        </div>
+      </form>
+    );
+  }
+}
+
+InstallerForm.propTypes = {
+  // i18next
+  t: PropTypes.func.isRequired,
+  // for input value
+  userName: PropTypes.string,
+  name: PropTypes.string,
+  email: PropTypes.string,
+  csrf: PropTypes.string,
+};
+
+export default translate()(InstallerForm);

+ 0 - 1
src/client/js/components/PageEditor/Editor.jsx

@@ -233,7 +233,6 @@ export default class Editor extends AbstractEditor {
         <Dropzone
             ref="dropzone"
             disableClick
-            disablePreview={true}
             accept={this.getDropzoneAccept()}
             className={this.getDropzoneClassName()}
             acceptClassName="dropzone-accepted"

+ 25 - 0
src/client/js/installer.js

@@ -0,0 +1,25 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { I18nextProvider } from 'react-i18next';
+
+import i18nFactory from './i18n';
+
+import InstallerForm    from './components/InstallerForm';
+
+const userlang = $('body').data('userlang');
+const i18n = i18nFactory(userlang);
+
+// render InstallerForm
+const installerFormElem = document.getElementById('installer-form');
+if (installerFormElem) {
+  const userName = installerFormElem.dataset.userName;
+  const name = installerFormElem.dataset.name;
+  const email = installerFormElem.dataset.email;
+  const csrf = installerFormElem.dataset.csrf;
+  ReactDOM.render(
+    <I18nextProvider i18n={i18n}>
+      <InstallerForm userName={userName} name={name} email={email} csrf={csrf} />
+    </I18nextProvider>,
+    installerFormElem
+  );
+}

+ 2 - 2
src/client/styles/scss/_editor-attachment.scss

@@ -14,7 +14,7 @@
 
     position: relative;   // against .overlay position: absolute
 
-    @include overlay-processing-style(overlay-dropzone-active, 2.5em);
+    @include overlay-processing-style(overlay-dropzone-active, 2.5em, 0.5em);
 
     // unuploadable or rejected
     &.dropzone-unuploadable, &.dropzone-rejected {
@@ -28,7 +28,7 @@
     }
     // uploading
     &.dropzone-uploading {
-      @include overlay-processing-style(overlay-dropzone-active, 2.5em);
+      @include overlay-processing-style(overlay-dropzone-active, 2.5em, 0.5em);
     }
 
     // unuploadable

+ 0 - 5
src/client/styles/scss/_editor-overlay.scss

@@ -23,11 +23,6 @@
     right: 0;
     bottom: 0;
     left: 0;
-    .overlay-content {
-      padding: 0.5em;
-      right: 0;
-      bottom: 0;
-    }
   }
 
   // loading keymap

+ 1 - 1
src/server/views/admin/users.html

@@ -134,7 +134,7 @@
               Reset user: <code id="admin-password-reset-done-user"></code>
               </p>
               <p>
-              New passwrod: <code id="admin-password-reset-done-password"></code>
+              New password: <code id="admin-password-reset-done-password"></code>
               </p>
             </div>
             <div class="modal-footer">

+ 14 - 50
src/server/views/installer.html

@@ -2,9 +2,7 @@
 
 {% block html_base_css %}installer nologin{% endblock %}
 
-{% block html_title %}{{ customTitle('セットアップ') }}{% endblock %}
-
-
+{% block html_title %}{{ customTitle(t('installer.setup')) }}{% endblock %}
 
 {#
  # Remove default contents
@@ -18,7 +16,10 @@
 {% block sidebar %}
 {% endblock %}
 
-
+{% block html_additional_headers %}
+  {% parent %}
+  <script src="{{ webpack_asset('js/installer.js') }}" defer></script>
+{% endblock %}
 
 {% block layout_main %}
 
@@ -45,53 +46,16 @@
 
     <div class="login-dialog p-t-10 p-b-10 col-sm-offset-4 col-sm-4" id="login-dialog">
       <p class="alert alert-success">
-        <strong>最初のアカウントの作成</strong><br>
-        <small>初めに作成するアカウントは、自動的に管理者権限が付与されます</small>
-      </p>
-
-      <p class="alert alert-warning p-b-10 p-t-10">
-        <small>現在の言語設定: {{ appGlobalLang() }}</small>
+        <strong>{{ t('installer.create_initial_account') }}</strong><br>
+        <small>{{ t('installer.initial_account_will_be_administrator_automatically') }}</small>
       </p>
 
-      <form role="form" action="/installer/createAdmin" method="post" id="register-form">
-
-        <div class="input-group" id="input-group-username">
-          <span class="input-group-addon"><i class="icon-user"></i></span>
-          <input type="text" class="form-control" placeholder="{{ t('User ID') }}" name="registerForm[username]" value="{{ req.body.registerForm.username }}" required>
-        </div>
-        <p class="help-block">
-          <span id="help-block-username"></span>
-        </p>
-
-        <div class="input-group">
-          <span class="input-group-addon"><i class="icon-tag"></i></span>
-          <input type="text" class="form-control" placeholder="{{ t('Name') }}" name="registerForm[name]" value="{{ googleName|default(req.body.registerForm.name) }}" required>
-        </div>
-
-        <div class="input-group">
-          <span class="input-group-addon"><i class="icon-envelope"></i></span>
-          <input type="email" class="form-control" placeholder="{{ t('Email') }}" name="registerForm[email]" value="{{ googleEmail|default(req.body.registerForm.email) }}" required>
-        </div>
-
-        <div class="input-group">
-          <span class="input-group-addon"><i class="icon-lock"></i></span>
-          <input type="password" class="form-control" placeholder="{{ t('Password') }}" name="registerForm[password]" required>
-        </div>
-
-        <input type="hidden" name="_csrf" value="{{ csrf() }}">
-        <div class="input-group m-t-30 m-b-20 d-flex justify-content-center">
-          <button type="submit" class="fcbtn btn btn-success btn-1b btn-register">
-            <span class="btn-label"><i class="icon-user-follow"></i></span>
-            {{ t('Create') }}
-          </button>
-        </div>
-
-        <div class="input-group m-t-30 d-flex justify-content-center">
-          <a href="https://growi.org" class="link-growi-org">
-            <span class="growi">GROWI</span>.<span class="org">ORG
-          </a>
-        </div>
-      </form>
+      <div id='installer-form'
+        data-user-name="{{ req.body.registerForm.username }}"
+        data-name="{{ googleName|default(req.body.registerForm.name) }}"
+        data-email="{{ googleEmail|default(req.body.registerForm.email) }}"
+        data-csrf="{{ csrf() }}">
+      </div>
     </div>
 
   </div>{# /.row #}
@@ -109,7 +73,7 @@ $(function() {
     $.getJSON('/_api/check_username', {username: username}, function(json) {
       if (!json.valid) {
         $('#help-block-username').html(
-          '<i class="icon-fw icon-ban"></i>このユーザーIDは利用できません。'
+          '<i class="icon-fw icon-ban"></i>{{ t("installer.unavaliable_user_id") }}'
         );
         $('#login-dialog').addClass('has-error');
         $('#input-group-username').addClass('has-error');

+ 15 - 11
yarn.lock

@@ -3991,13 +3991,13 @@ google-p12-pem@^1.0.0:
     node-forge "^0.7.1"
     pify "^3.0.0"
 
-googleapis-common@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/googleapis-common/-/googleapis-common-0.3.0.tgz#97ba111f7420367e636a30a2b87be4a7f220c7e9"
+googleapis-common@^0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/googleapis-common/-/googleapis-common-0.4.0.tgz#3b3c2c26f731dcf72101239e70dfa3d677e079e6"
   dependencies:
     axios "^0.18.0"
     google-auth-library "^2.0.0"
-    pify "^3.0.0"
+    pify "^4.0.0"
     qs "^6.5.2"
     url-template "^2.0.8"
     uuid "^3.2.1"
@@ -4010,12 +4010,12 @@ googleapis@^16.0.0:
     google-auth-library "~0.10.0"
     string-template "~1.0.0"
 
-googleapis@^34.0.0:
-  version "34.0.0"
-  resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-34.0.0.tgz#15323c2334edeff3bae500faeec7e15ea6fb0047"
+googleapis@^35.0.0:
+  version "35.0.0"
+  resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-35.0.0.tgz#958503baa2d32b2702aed7308f8b6abd15a9b5c1"
   dependencies:
     google-auth-library "^2.0.0"
-    googleapis-common "^0.3.0"
+    googleapis-common "^0.4.0"
 
 graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
   version "4.1.11"
@@ -6828,6 +6828,10 @@ pify@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
 
+pify@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
+
 pikaday@1.5.1:
   version "1.5.1"
   resolved "http://registry.npmjs.org/pikaday/-/pikaday-1.5.1.tgz#0a48549bc1a14ea1d08c44074d761bc2f2bfcfd3"
@@ -7476,9 +7480,9 @@ react-dom@^16.4.1:
     object-assign "^4.1.1"
     prop-types "^15.6.0"
 
-react-dropzone@^6.0.2:
-  version "6.0.2"
-  resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-6.0.2.tgz#53a9fdc7b9125c5f2aa9d985a75878b200ee241c"
+react-dropzone@^7.0.1:
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-7.0.1.tgz#bc76bc1686fb47ed0c8301f968fffa6aecdff47b"
   dependencies:
     attr-accept "^1.1.3"
     prop-types "^15.6.2"