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

Merge branch 'master' into fix/reply-comment

itizawa 6 лет назад
Родитель
Сommit
d1f8741c07

+ 8 - 0
CHANGES.md

@@ -2,7 +2,15 @@
 
 
 ## v3.6.8-RC
 ## v3.6.8-RC
 
 
+* Improvement: Show page history side-by-side
 * Improvement: Optimize markdown rendering
 * Improvement: Optimize markdown rendering
+* Improvement: Reactify admin pages (Navigation)
+* Support: Update libs
+    * cross-env
+    * mkdirp
+    * diff2html
+    * jest
+    * stylelint
 
 
 ## v3.6.7
 ## v3.6.7
 
 

+ 5 - 5
package.json

@@ -85,7 +85,7 @@
     "connect-mongo": "^3.0.0",
     "connect-mongo": "^3.0.0",
     "connect-redis": "^3.3.0",
     "connect-redis": "^3.3.0",
     "cookie-parser": "^1.4.3",
     "cookie-parser": "^1.4.3",
-    "cross-env": "^6.0.3",
+    "cross-env": "^7.0.0",
     "csrf": "^3.1.0",
     "csrf": "^3.1.0",
     "date-fns": "^2.0.0",
     "date-fns": "^2.0.0",
     "diff": "^4.0.1",
     "diff": "^4.0.1",
@@ -112,7 +112,7 @@
     "md5": "^2.2.1",
     "md5": "^2.2.1",
     "method-override": "^3.0.0",
     "method-override": "^3.0.0",
     "migrate-mongo": "^7.0.1",
     "migrate-mongo": "^7.0.1",
-    "mkdirp": "~0.5.1",
+    "mkdirp": "^1.0.3",
     "module-alias": "^2.0.6",
     "module-alias": "^2.0.6",
     "mongoose": "5.4.4",
     "mongoose": "5.4.4",
     "mongoose-gridfs": "^1.2.2",
     "mongoose-gridfs": "^1.2.2",
@@ -172,7 +172,7 @@
     "core-js": "=2.6.9",
     "core-js": "=2.6.9",
     "css-loader": "^3.0.0",
     "css-loader": "^3.0.0",
     "csv-to-markdown-table": "^1.0.1",
     "csv-to-markdown-table": "^1.0.1",
-    "diff2html": "^2.3.3",
+    "diff2html": "^3.1.2",
     "eazy-logger": "^3.0.2",
     "eazy-logger": "^3.0.2",
     "eslint": "^6.0.1",
     "eslint": "^6.0.1",
     "eslint-config-weseek": "^1.0.3",
     "eslint-config-weseek": "^1.0.3",
@@ -184,7 +184,7 @@
     "hard-source-webpack-plugin": "^0.13.1",
     "hard-source-webpack-plugin": "^0.13.1",
     "i18next-browser-languagedetector": "^4.0.1",
     "i18next-browser-languagedetector": "^4.0.1",
     "imports-loader": "^0.8.0",
     "imports-loader": "^0.8.0",
-    "jest": "^24.8.0",
+    "jest": "^25.1.0",
     "jquery-slimscroll": "^1.3.8",
     "jquery-slimscroll": "^1.3.8",
     "jquery-ui": "^1.12.1",
     "jquery-ui": "^1.12.1",
     "jquery.cookie": "~1.4.1",
     "jquery.cookie": "~1.4.1",
@@ -230,7 +230,7 @@
     "simple-load-script": "^1.0.2",
     "simple-load-script": "^1.0.2",
     "socket.io-client": "^2.0.3",
     "socket.io-client": "^2.0.3",
     "style-loader": "^1.0.0",
     "style-loader": "^1.0.0",
-    "stylelint": "^12.0.1",
+    "stylelint": "^13.2.0",
     "stylelint-config-recess-order": "^2.0.1",
     "stylelint-config-recess-order": "^2.0.1",
     "swagger-jsdoc": "^3.4.0",
     "swagger-jsdoc": "^3.4.0",
     "swagger2openapi": "^5.3.1",
     "swagger2openapi": "^5.3.1",

+ 2 - 0
src/client/js/bootstrap.jsx

@@ -4,6 +4,7 @@ import loggerFactory from '@alias/logger';
 import Xss from '@commons/service/xss';
 import Xss from '@commons/service/xss';
 
 
 import HeaderSearchBox from './components/HeaderSearchBox';
 import HeaderSearchBox from './components/HeaderSearchBox';
+import PersonalDropdown from './components/Navbar/PersonalDropdown';
 import StaffCredit from './components/StaffCredit/StaffCredit';
 import StaffCredit from './components/StaffCredit/StaffCredit';
 
 
 import AppContainer from './services/AppContainer';
 import AppContainer from './services/AppContainer';
@@ -37,6 +38,7 @@ appContainer.injectToWindow();
 const componentMappings = {
 const componentMappings = {
   'search-top': <HeaderSearchBox />,
   'search-top': <HeaderSearchBox />,
   'search-sidebar': <HeaderSearchBox crowi={appContainer} />,
   'search-sidebar': <HeaderSearchBox crowi={appContainer} />,
+  'personal-dropdown': <PersonalDropdown />,
 
 
   'staff-credit': <StaffCredit />,
   'staff-credit': <StaffCredit />,
 };
 };

+ 61 - 0
src/client/js/components/Navbar/PersonalDropdown.jsx

@@ -0,0 +1,61 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { withTranslation } from 'react-i18next';
+
+import { createSubscribedElement } from '../UnstatedUtils';
+import AppContainer from '../../services/AppContainer';
+
+import UserPicture from '../User/UserPicture';
+
+const PersonalDropdown = (props) => {
+
+  const { t, appContainer } = props;
+  const username = appContainer.me;
+  const user = appContainer.findUser(username);
+
+  const logoutHandler = () => {
+    const { interceptorManager } = appContainer;
+
+    const context = {
+      user,
+      currentPagePath: decodeURIComponent(window.location.pathname),
+    };
+    interceptorManager.process('logout', context);
+
+    window.location.href = '/logout';
+  };
+
+  return (
+    <>
+      <a className="dropdown-toggle waves-effect waves-light" data-toggle="dropdown">
+        <UserPicture user={user} withoutLink />&nbsp;{user.name}
+      </a>
+      <ul className="dropdown-menu dropdown-menu-right">
+        <li><a href={`/user/${user.username}`}><i className="icon-fw icon-home"></i>{ t('Home') }</a></li>
+        <li><a href="/me"><i className="icon-fw icon-wrench"></i>{ t('User Settings') }</a></li>
+        <li role="separator" className="divider"></li>
+        <li><a href={`/user/${user.username}#user-draft-list`}><i className="icon-fw icon-docs"></i>{ t('List Drafts') }</a></li>
+        <li><a href="/trash"><i className="icon-fw icon-trash"></i>{ t('Deleted Pages') }</a></li>
+        <li role="separator" className="divider"></li>
+        <li><a role="button" onClick={logoutHandler}><i className="icon-fw icon-power"></i>{ t('Sign out') }</a></li>
+      </ul>
+    </>
+  );
+
+};
+
+/**
+ * Wrapper component for using unstated
+ */
+const PersonalDropdownWrapper = (props) => {
+  return createSubscribedElement(PersonalDropdown, props, [AppContainer]);
+};
+
+
+PersonalDropdown.propTypes = {
+  t: PropTypes.func.isRequired, //  i18next
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+};
+
+export default withTranslation()(PersonalDropdownWrapper);

+ 6 - 2
src/client/js/components/PageHistory/RevisionDiff.jsx

@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
 import { createPatch } from 'diff';
 import { createPatch } from 'diff';
-import { Diff2Html } from 'diff2html';
+import { html } from 'diff2html';
 
 
 export default class RevisionDiff extends React.Component {
 export default class RevisionDiff extends React.Component {
 
 
@@ -29,8 +29,12 @@ export default class RevisionDiff extends React.Component {
         previousText,
         previousText,
         currentRevision.body,
         currentRevision.body,
       );
       );
+      const option = {
+        drawFileList: false,
+        outputFormat: 'side-by-side',
+      };
 
 
-      diffViewHTML = Diff2Html.getPrettyHtml(patch);
+      diffViewHTML = html(patch, option);
     }
     }
 
 
     const diffView = { __html: diffViewHTML };
     const diffView = { __html: diffViewHTML };

+ 1 - 4
src/client/styles/scss/_page.scss

@@ -1,5 +1,5 @@
 // import diff2html styles
 // import diff2html styles
-@import '~diff2html/dist/diff2html.css';
+@import '~diff2html/bundles/css/diff2html.min.css';
 
 
 .main-container {
 .main-container {
   // padding controll of .header-wrap and .content-main are moved to _layout and _form
   // padding controll of .header-wrap and .content-main are moved to _layout and _form
@@ -8,7 +8,6 @@
    * header
    * header
    */
    */
   header {
   header {
-
     // the container of h1
     // the container of h1
     div.title-container {
     div.title-container {
       padding-right: 5px;
       padding-right: 5px;
@@ -39,7 +38,6 @@
 
 
     // change button opacity
     // change button opacity
     &:hover {
     &:hover {
-
       .btn.btn-copy,
       .btn.btn-copy,
       .btn-copy-link,
       .btn-copy-link,
       .btn.btn-edit,
       .btn.btn-edit,
@@ -116,7 +114,6 @@
 .main-container .main .content-main .revision-history {
 .main-container .main .content-main .revision-history {
   .revision-history-list {
   .revision-history-list {
     .revision-history-outer {
     .revision-history-outer {
-
       // add border-top except of first element
       // add border-top except of first element
       &:not(:first-of-type) {
       &:not(:first-of-type) {
         border-top: 1px solid $border;
         border-top: 1px solid $border;

+ 1 - 15
src/server/views/layout/layout.html

@@ -141,21 +141,7 @@
             <i class="icon-question"></i><span>{{ t('Help') }}</span><span class="text-muted small"><i class="icon-share-alt"></i></span>
             <i class="icon-question"></i><span>{{ t('Help') }}</span><span class="text-muted small"><i class="icon-share-alt"></i></span>
           </a>
           </a>
         </li>
         </li>
-        <li class="dropdown">
-          <a class="dropdown-toggle waves-effect waves-light" data-toggle="dropdown">
-            <img src="{{ user|picture }}" class="picture img-circle" width="25" /> <span class="user-name">{{ user.name }}</span>
-          </a>
-          <ul class="dropdown-menu dropdown-menu-right">
-            <li><a href="/user/{{ user.username }}"><i class="icon-fw icon-home"></i>{{ t('Home') }}</a></li>
-            <li><a href="/me"><i class="icon-fw icon-wrench"></i>{{ t('User Settings') }}</a></li>
-            <li role="separator" class="divider"></li>
-            <li><a href="/user/{{ user.username }}#user-draft-list"><i class="icon-fw icon-docs"></i>{{ t('List Drafts') }}</a></li>
-            <li><a href="/trash"><i class="icon-fw icon-trash"></i>{{ t('Deleted Pages') }}</a></li>
-            <li role="separator" class="divider"></li>
-            <li><a href="/logout"><i class="icon-fw icon-power"></i>{{ t('Sign out') }}</a></li>
-          </ul>
-          <!-- /.dropdown-messages -->
-        </li>
+        <li id="personal-dropdown" class="dropdown"></li>
         {% else %}
         {% else %}
         <li id="login-user"><a href="/login">Login</a></li>
         <li id="login-user"><a href="/login">Login</a></li>
         {% endif %}
         {% endif %}

Разница между файлами не показана из-за своего большого размера
+ 436 - 228
yarn.lock


Некоторые файлы не были показаны из-за большого количества измененных файлов