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

Merge pull request #2340 from weseek/master

release v4.0.3
Yuki Takei 5 лет назад
Родитель
Сommit
b6d7e93108
41 измененных файлов с 442 добавлено и 183 удалено
  1. 14 2
      CHANGES.md
  2. 1 1
      package.json
  3. 5 0
      resource/locales/en-US/translation.json
  4. 5 0
      resource/locales/ja/translation.json
  5. 0 2
      src/client/js/app.jsx
  6. 1 1
      src/client/js/components/Admin/Customize/CustomizeScriptSetting.jsx
  7. 2 2
      src/client/js/components/LoginForm.jsx
  8. 1 1
      src/client/js/components/Navbar/PersonalDropdown.jsx
  9. 35 16
      src/client/js/components/Page/CopyDropdown.jsx
  10. 0 1
      src/client/js/components/PageDuplicateModal.jsx
  11. 2 2
      src/client/js/components/PageEditor.jsx
  12. 8 4
      src/client/js/components/PageEditor/TextAreaEditor.jsx
  13. 0 1
      src/client/js/components/PagePathAutoComplete.jsx
  14. 7 7
      src/client/js/components/SearchForm.jsx
  15. 5 4
      src/client/js/services/AppContainer.js
  16. 0 1
      src/client/styles/scss/_layout.scss
  17. 10 55
      src/client/styles/scss/_login.scss
  18. 3 0
      src/client/styles/scss/_navbar.scss
  19. 4 10
      src/client/styles/scss/_on-edit.scss
  20. 5 0
      src/client/styles/scss/_override-bootstrap.scss
  21. 57 3
      src/client/styles/scss/_search.scss
  22. 1 1
      src/client/styles/scss/atoms/_buttons.scss
  23. 31 0
      src/client/styles/scss/atoms/_custom_control.scss
  24. 3 0
      src/client/styles/scss/atoms/_nav.scss
  25. 8 0
      src/client/styles/scss/style-app.scss
  26. 81 0
      src/client/styles/scss/theme/_apply-colors-dark.scss
  27. 57 6
      src/client/styles/scss/theme/_apply-colors-light.scss
  28. 5 0
      src/client/styles/scss/theme/_apply-colors.scss
  29. 10 3
      src/client/styles/scss/theme/antarctic.scss
  30. 15 11
      src/client/styles/scss/theme/christmas.scss
  31. 14 5
      src/client/styles/scss/theme/spring.scss
  32. 13 7
      src/client/styles/scss/theme/wood.scss
  33. 1 1
      src/lib/components/PagePathHierarchicalLink.jsx
  34. 8 12
      src/server/views/layout-growi/base/layout.html
  35. 6 8
      src/server/views/layout-growi/widget/liker-and-seenusers.html
  36. 1 1
      src/server/views/layout/layout.html
  37. 3 3
      src/server/views/login/error.html
  38. 1 1
      src/server/views/widget/not_found_tabs.html
  39. 6 6
      src/server/views/widget/page_tabs.html
  40. 1 1
      src/server/views/widget/page_tabs_kibela.html
  41. 12 4
      src/server/views/widget/user_page_content.html

+ 14 - 2
CHANGES.md

@@ -1,9 +1,21 @@
 # CHANGES
 # CHANGES
 
 
-## v4.0.2-RC
+## v4.0.3-RC
+
+* Feature: Copy page path dropdown with Append params switch
+* Improvement: Truncate overflowed user browsing history
+* Improvement: Tabs appearance on mobile
+* Improvement: Search help appearance on mobile
+* Improvement: Accessibility of login page
+* Fix: Editor was broken by long lines
+* Fix: Editor doesn't work on mobile
+* Fix: Word break in Recent Updated contents
+* Fix: navbar is broken on Safari
+
+## v4.0.2
 
 
 * Fix: Internal Server Error occurred when the guest user access to the pages that has likes
 * Fix: Internal Server Error occurred when the guest user access to the pages that has likes
-* Fix: Some buttons are broken in Safari
+* Fix: Some buttons are broken on Safari
 
 
 ## v4.0.1
 ## v4.0.1
 
 

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "growi",
   "name": "growi",
-  "version": "4.0.2-RC",
+  "version": "4.0.3-RC",
   "description": "Team collaboration software using markdown",
   "description": "Team collaboration software using markdown",
   "tags": [
   "tags": [
     "wiki",
     "wiki",

+ 5 - 0
resource/locales/en-US/translation.json

@@ -678,5 +678,10 @@
     "export_menu": "Export Menu",
     "export_menu": "Export Menu",
     "download": "Download",
     "download": "Download",
     "delete": "Delete"
     "delete": "Delete"
+  },
+  "login": {
+    "Sign in error": "Login error",
+    "Registration successful": "Registration successful",
+    "Setup": "Setup"
   }
   }
 }
 }

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

@@ -667,5 +667,10 @@
     "export_menu": "エクスポートメニュー",
     "export_menu": "エクスポートメニュー",
     "download": "ダウンロード",
     "download": "ダウンロード",
     "delete": "削除"
     "delete": "削除"
+  },
+  "login": {
+    "Sign in error": "ログインエラー",
+    "Registration successful": "登録完了",
+    "Setup": "セットアップ"
   }
   }
 }
 }

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

@@ -25,7 +25,6 @@ import PageManagement from './components/Page/PageManagement';
 import TrashPageAlert from './components/Page/TrashPageAlert';
 import TrashPageAlert from './components/Page/TrashPageAlert';
 import PageAttachment from './components/PageAttachment';
 import PageAttachment from './components/PageAttachment';
 import PageStatusAlert from './components/PageStatusAlert';
 import PageStatusAlert from './components/PageStatusAlert';
-import PagePathAutoComplete from './components/PagePathAutoComplete';
 import RecentCreated from './components/RecentCreated/RecentCreated';
 import RecentCreated from './components/RecentCreated/RecentCreated';
 import MyDraftList from './components/MyDraftList/MyDraftList';
 import MyDraftList from './components/MyDraftList/MyDraftList';
 import UserPictureList from './components/User/UserPictureList';
 import UserPictureList from './components/User/UserPictureList';
@@ -95,7 +94,6 @@ if (pageContainer.state.pageId != null) {
     'revision-toc': <TableOfContents />,
     'revision-toc': <TableOfContents />,
     'seen-user-list': <UserPictureList userIds={pageContainer.state.seenUserIds} />,
     'seen-user-list': <UserPictureList userIds={pageContainer.state.seenUserIds} />,
     'liker-list': <UserPictureList userIds={pageContainer.state.likerUserIds} />,
     'liker-list': <UserPictureList userIds={pageContainer.state.likerUserIds} />,
-    'rename-page-name-input': <PagePathAutoComplete crowi={appContainer} initializedPath={pageContainer.state.path} />,
 
 
     'user-created-list': <RecentCreated />,
     'user-created-list': <RecentCreated />,
     'user-draft-list': <MyDraftList />,
     'user-draft-list': <MyDraftList />,

+ 1 - 1
src/client/js/components/Admin/Customize/CustomizeScriptSetting.jsx

@@ -59,7 +59,7 @@ class CustomizeScriptSetting extends React.Component {
               Placeholders:<br />
               Placeholders:<br />
               (Available after <code>load</code> event)
               (Available after <code>load</code> event)
             </div>
             </div>
-            <table className="table table-borderless table-sm form-text text-muted offset-1">
+            <table className="table table-borderless table-sm form-text text-muted offset-1 col-11">
               <tbody>
               <tbody>
                 <tr>
                 <tr>
                   <th className="text-right"><code>$</code></th>
                   <th className="text-right"><code>$</code></th>

+ 2 - 2
src/client/js/components/LoginForm.jsx

@@ -116,7 +116,7 @@ class LoginForm extends React.Component {
 
 
     return (
     return (
       <>
       <>
-        <div className="border-top border-bottom">
+        <div className="grw-external-auth-form border-top border-bottom">
           <div id="external-auth" className={`external-auth ${collapsibleClass}`}>
           <div id="external-auth" className={`external-auth ${collapsibleClass}`}>
             <div className="row mt-2">
             <div className="row mt-2">
               {Object.keys(objOfIsExternalAuthEnableds).map((auth) => {
               {Object.keys(objOfIsExternalAuthEnableds).map((auth) => {
@@ -131,7 +131,7 @@ class LoginForm extends React.Component {
         <div className="text-center">
         <div className="text-center">
           <button
           <button
             type="button"
             type="button"
-            className="btn btn-secondary btn-sm rounded-0 mb-3"
+            className="btn btn-secondary btn-external-auth-tab btn-sm rounded-0 mb-3"
             data-toggle={isExternalAuthCollapsible ? 'collapse' : ''}
             data-toggle={isExternalAuthCollapsible ? 'collapse' : ''}
             data-target="#external-auth"
             data-target="#external-auth"
             aria-expanded="false"
             aria-expanded="false"

+ 1 - 1
src/client/js/components/Navbar/PersonalDropdown.jsx

@@ -107,7 +107,7 @@ const PersonalDropdown = (props) => {
 
 
         <div className="dropdown-divider"></div>
         <div className="dropdown-divider"></div>
 
 
-        <a className="dropdown-item" onClick={logoutHandler}><i className="icon-fw icon-power"></i>{ t('Sign out') }</a>
+        <button type="button" className="dropdown-item" onClick={logoutHandler}><i className="icon-fw icon-power"></i>{ t('Sign out') }</button>
       </div>
       </div>
 
 
     </>
     </>

+ 35 - 16
src/client/js/components/Page/CopyDropdown.jsx

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 import { withTranslation } from 'react-i18next';
 
 
 import {
 import {
-  Dropdown, DropdownToggle, DropdownMenu, DropdownItem,
+  UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem,
   Tooltip,
   Tooltip,
 } from 'reactstrap';
 } from 'reactstrap';
 
 
@@ -18,6 +18,7 @@ class CopyDropdown extends React.Component {
     this.state = {
     this.state = {
       dropdownOpen: false,
       dropdownOpen: false,
       tooltipOpen: false,
       tooltipOpen: false,
+      isParamsAppended: true,
     };
     };
 
 
     this.toggle = this.toggle.bind(this);
     this.toggle = this.toggle.bind(this);
@@ -39,13 +40,22 @@ class CopyDropdown extends React.Component {
     }, 1000);
     }, 1000);
   }
   }
 
 
-  generatePagePathWithParams() {
-    const { pagePath } = this.props;
+  get uriParams() {
+    const { isParamsAppended } = this.state;
+
+    if (!isParamsAppended) {
+      return '';
+    }
+
     const {
     const {
       search, hash,
       search, hash,
     } = window.location;
     } = window.location;
+    return `${search}${hash}`;
+  }
 
 
-    return `${pagePath}${search}${hash}`;
+  generatePagePathWithParams() {
+    const { pagePath } = this.props;
+    return decodeURI(`${pagePath}${this.uriParams}`);
   }
   }
 
 
   generatePagePathUrl() {
   generatePagePathUrl() {
@@ -55,25 +65,18 @@ class CopyDropdown extends React.Component {
 
 
   generatePermalink() {
   generatePermalink() {
     const { pageId } = this.props;
     const { pageId } = this.props;
-    const { location } = window;
 
 
     if (pageId == null) {
     if (pageId == null) {
       return null;
       return null;
     }
     }
 
 
-    const {
-      origin, search, hash,
-    } = location;
-    return `${origin}/${pageId}${search}${hash}`;
+    return decodeURI(`${origin}/${pageId}${this.uriParams}`);
   }
   }
 
 
   generateMarkdownLink() {
   generateMarkdownLink() {
     const { pagePath } = this.props;
     const { pagePath } = this.props;
-    const {
-      search, hash,
-    } = window.location;
 
 
-    const label = `${pagePath}${search}${hash}`;
+    const label = decodeURI(`${pagePath}${this.uriParams}`);
     const permalink = this.generatePermalink();
     const permalink = this.generatePermalink();
 
 
     return `[${label}](${permalink})`;
     return `[${label}](${permalink})`;
@@ -88,6 +91,7 @@ class CopyDropdown extends React.Component {
 
 
   render() {
   render() {
     const { t, pageId } = this.props;
     const { t, pageId } = this.props;
+    const { isParamsAppended } = this.state;
 
 
     const pagePathWithParams = this.generatePagePathWithParams();
     const pagePathWithParams = this.generatePagePathWithParams();
     const pagePathUrl = this.generatePagePathUrl();
     const pagePathUrl = this.generatePagePathUrl();
@@ -97,7 +101,7 @@ class CopyDropdown extends React.Component {
 
 
     return (
     return (
       <>
       <>
-        <Dropdown id="copyPagePathDropdown" className="grw-copy-dropdown" isOpen={this.state.dropdownOpen} toggle={this.toggle}>
+        <UncontrolledDropdown id="copyPagePathDropdown" className="grw-copy-dropdown">
 
 
           <DropdownToggle
           <DropdownToggle
             caret
             caret
@@ -108,7 +112,22 @@ class CopyDropdown extends React.Component {
           </DropdownToggle>
           </DropdownToggle>
 
 
           <DropdownMenu>
           <DropdownMenu>
-            <DropdownItem header className="px-3">{ t('copy_to_clipboard.Copy to clipboard') }</DropdownItem>
+
+            <div className="d-flex align-items-center justify-content-between">
+              <DropdownItem header className="px-3">
+                { t('copy_to_clipboard.Copy to clipboard') }
+              </DropdownItem>
+              <div className="px-3 custom-control custom-switch custom-switch-sm">
+                <input
+                  type="checkbox"
+                  id="customSwitchForParams"
+                  className="custom-control-input"
+                  checked={isParamsAppended}
+                  onChange={e => this.setState({ isParamsAppended: !isParamsAppended })}
+                />
+                <label className="custom-control-label small" htmlFor="customSwitchForParams">Append params</label>
+              </div>
+            </div>
 
 
             <DropdownItem divider className="my-0"></DropdownItem>
             <DropdownItem divider className="my-0"></DropdownItem>
 
 
@@ -162,7 +181,7 @@ class CopyDropdown extends React.Component {
             )}
             )}
           </DropdownMenu>
           </DropdownMenu>
 
 
-        </Dropdown>
+        </UncontrolledDropdown>
 
 
         <Tooltip placement="bottom" isOpen={this.state.tooltipOpen} target="copyPagePathDropdown" fade={false}>
         <Tooltip placement="bottom" isOpen={this.state.tooltipOpen} target="copyPagePathDropdown" fade={false}>
           copied!
           copied!

+ 0 - 1
src/client/js/components/PageDuplicateModal.jsx

@@ -82,7 +82,6 @@ const PageDuplicateModal = (props) => {
                 <PagePathAutoComplete
                 <PagePathAutoComplete
                   crowi={appContainer}
                   crowi={appContainer}
                   initializedPath={path}
                   initializedPath={path}
-                  addTrailingSlash
                   onSubmit={ppacSubmitHandler}
                   onSubmit={ppacSubmitHandler}
                   onInputChange={ppacInputChangeHandler}
                   onInputChange={ppacInputChangeHandler}
                 />
                 />

+ 2 - 2
src/client/js/components/PageEditor.jsx

@@ -289,7 +289,7 @@ class PageEditor extends React.Component {
 
 
     return (
     return (
       <div className="d-flex flex-wrap">
       <div className="d-flex flex-wrap">
-        <div className="page-editor-editor-container" style={{ flex: 1 }}>
+        <div className="page-editor-editor-container flex-grow-1 flex-basis-0 mw-0">
           <Editor
           <Editor
             ref={(c) => { this.editor = c }}
             ref={(c) => { this.editor = c }}
             value={this.state.markdown}
             value={this.state.markdown}
@@ -305,7 +305,7 @@ class PageEditor extends React.Component {
             onSave={this.onSaveWithShortcut}
             onSave={this.onSaveWithShortcut}
           />
           />
         </div>
         </div>
-        <div className="d-none d-xl-block page-editor-preview-container" style={{ flex: 1 }}>
+        <div className="d-none d-xl-block page-editor-preview-container flex-grow-1 flex-basis-0 mw-0">
           <Preview
           <Preview
             markdown={this.state.markdown}
             markdown={this.state.markdown}
             // eslint-disable-next-line no-return-assign
             // eslint-disable-next-line no-return-assign

+ 8 - 4
src/client/js/components/PageEditor/TextAreaEditor.jsx

@@ -3,6 +3,8 @@ import React from 'react';
 
 
 import InterceptorManager from '@commons/service/interceptor-manager';
 import InterceptorManager from '@commons/service/interceptor-manager';
 
 
+import { Input } from 'reactstrap';
+
 import AbstractEditor from './AbstractEditor';
 import AbstractEditor from './AbstractEditor';
 
 
 import pasteHelper from './PasteHelper';
 import pasteHelper from './PasteHelper';
@@ -21,6 +23,8 @@ export default class TextAreaEditor extends AbstractEditor {
       isGfmMode: this.props.isGfmMode,
       isGfmMode: this.props.isGfmMode,
     };
     };
 
 
+    this.textarea = React.createRef();
+
     this.init();
     this.init();
 
 
     this.handleEnterKey = this.handleEnterKey.bind(this);
     this.handleEnterKey = this.handleEnterKey.bind(this);
@@ -249,10 +253,10 @@ export default class TextAreaEditor extends AbstractEditor {
   render() {
   render() {
     return (
     return (
       <React.Fragment>
       <React.Fragment>
-        <input
-          componentClass="textarea"
-          className="textarea-editor"
-          inputRef={(ref) => { this.textarea = ref }}
+        <Input
+          type="textarea"
+          className="textarea-editor shadow-none"
+          innerRef={(c) => { this.textarea = c }}
           defaultValue={this.state.value}
           defaultValue={this.state.value}
           onChange={(e) => {
           onChange={(e) => {
           if (this.props.onChange != null) {
           if (this.props.onChange != null) {

+ 0 - 1
src/client/js/components/PagePathAutoComplete.jsx

@@ -61,7 +61,6 @@ PagePathAutoComplete.propTypes = {
 
 
 PagePathAutoComplete.defaultProps = {
 PagePathAutoComplete.defaultProps = {
   initializedPath: '/',
   initializedPath: '/',
-  addTrailingSlash: true,
 };
 };
 
 
 export default PagePathAutoComplete;
 export default PagePathAutoComplete;

+ 7 - 7
src/client/js/components/SearchForm.jsx

@@ -62,37 +62,37 @@ class SearchForm extends React.Component {
         </caption>
         </caption>
         <tbody>
         <tbody>
           <tr>
           <tr>
-            <th className="text-right py-2">
+            <th className="py-2">
               <code>word1</code> <code>word2</code><br></br>
               <code>word1</code> <code>word2</code><br></br>
               <small>({ t('search_help.and.syntax help') })</small>
               <small>({ t('search_help.and.syntax help') })</small>
             </th>
             </th>
             <td><h6 className="m-0">{ t('search_help.and.desc', { word1: 'word1', word2: 'word2' }) }</h6></td>
             <td><h6 className="m-0">{ t('search_help.and.desc', { word1: 'word1', word2: 'word2' }) }</h6></td>
           </tr>
           </tr>
           <tr>
           <tr>
-            <th className="text-right py-2">
+            <th className="py-2">
               <code>&quot;This is GROWI&quot;</code><br></br>
               <code>&quot;This is GROWI&quot;</code><br></br>
               <small>({ t('search_help.phrase.syntax help') })</small>
               <small>({ t('search_help.phrase.syntax help') })</small>
             </th>
             </th>
             <td><h6 className="m-0">{ t('search_help.phrase.desc', { phrase: 'This is GROWI' }) }</h6></td>
             <td><h6 className="m-0">{ t('search_help.phrase.desc', { phrase: 'This is GROWI' }) }</h6></td>
           </tr>
           </tr>
           <tr>
           <tr>
-            <th className="text-right py-2"><code>-keyword</code></th>
+            <th className="py-2"><code>-keyword</code></th>
             <td><h6 className="m-0">{ t('search_help.exclude.desc', { word: 'keyword' }) }</h6></td>
             <td><h6 className="m-0">{ t('search_help.exclude.desc', { word: 'keyword' }) }</h6></td>
           </tr>
           </tr>
           <tr>
           <tr>
-            <th className="text-right py-2"><code>prefix:/user/</code></th>
+            <th className="py-2"><code>prefix:/user/</code></th>
             <td><h6 className="m-0">{ t('search_help.prefix.desc', { path: '/user/' }) }</h6></td>
             <td><h6 className="m-0">{ t('search_help.prefix.desc', { path: '/user/' }) }</h6></td>
           </tr>
           </tr>
           <tr>
           <tr>
-            <th className="text-right py-2"><code>-prefix:/user/</code></th>
+            <th className="py-2"><code>-prefix:/user/</code></th>
             <td><h6 className="m-0">{ t('search_help.exclude_prefix.desc', { path: '/user/' }) }</h6></td>
             <td><h6 className="m-0">{ t('search_help.exclude_prefix.desc', { path: '/user/' }) }</h6></td>
           </tr>
           </tr>
           <tr>
           <tr>
-            <th className="text-right py-2"><code>tag:wiki</code></th>
+            <th className="py-2"><code>tag:wiki</code></th>
             <td><h6 className="m-0">{ t('search_help.tag.desc', { tag: 'wiki' }) }</h6></td>
             <td><h6 className="m-0">{ t('search_help.tag.desc', { tag: 'wiki' }) }</h6></td>
           </tr>
           </tr>
           <tr>
           <tr>
-            <th className="text-right py-2"><code>-tag:wiki</code></th>
+            <th className="py-2"><code>-tag:wiki</code></th>
             <td><h6 className="m-0">{ t('search_help.exclude_tag.desc', { tag: 'wiki' }) }</h6></td>
             <td><h6 className="m-0">{ t('search_help.exclude_tag.desc', { tag: 'wiki' }) }</h6></td>
           </tr>
           </tr>
         </tbody>
         </tbody>

+ 5 - 4
src/client/js/services/AppContainer.js

@@ -116,9 +116,9 @@ export default class AppContainer extends Container {
   }
   }
 
 
   async initColorScheme() {
   async initColorScheme() {
-    const switchStateByMediaQuery = (mql) => {
+    const switchStateByMediaQuery = async(mql) => {
       const preferDarkMode = mql.matches;
       const preferDarkMode = mql.matches;
-      this.setState({ preferDarkModeByMediaQuery: preferDarkMode });
+      await this.setState({ preferDarkModeByMediaQuery: preferDarkMode });
 
 
       this.applyColorScheme();
       this.applyColorScheme();
     };
     };
@@ -127,13 +127,13 @@ export default class AppContainer extends Container {
     // add event listener
     // add event listener
     mqlForDarkMode.addListener(switchStateByMediaQuery);
     mqlForDarkMode.addListener(switchStateByMediaQuery);
 
 
-    // restore settings from localStorage
+    // initialize1: restore settings from localStorage
     const { localStorage } = window;
     const { localStorage } = window;
     if (localStorage.preferDarkModeByUser != null) {
     if (localStorage.preferDarkModeByUser != null) {
       await this.setState({ preferDarkModeByUser: localStorage.preferDarkModeByUser === 'true' });
       await this.setState({ preferDarkModeByUser: localStorage.preferDarkModeByUser === 'true' });
     }
     }
 
 
-    // initialize
+    // initialize2: check media query
     switchStateByMediaQuery(mqlForDarkMode);
     switchStateByMediaQuery(mqlForDarkMode);
   }
   }
 
 
@@ -410,6 +410,7 @@ export default class AppContainer extends Container {
    */
    */
   applyColorScheme() {
   applyColorScheme() {
     const { preferDarkModeByMediaQuery, preferDarkModeByUser } = this.state;
     const { preferDarkModeByMediaQuery, preferDarkModeByUser } = this.state;
+
     let isDarkMode = preferDarkModeByMediaQuery;
     let isDarkMode = preferDarkModeByMediaQuery;
     if (preferDarkModeByUser != null) {
     if (preferDarkModeByUser != null) {
       isDarkMode = preferDarkModeByUser;
       isDarkMode = preferDarkModeByUser;

+ 0 - 1
src/client/styles/scss/_layout.scss

@@ -15,7 +15,6 @@ body {
 }
 }
 
 
 #page-wrapper {
 #page-wrapper {
-  min-width: 0;
   margin-top: $grw-navbar-height + $grw-navbar-border-width;
   margin-top: $grw-navbar-height + $grw-navbar-border-width;
 }
 }
 
 

+ 10 - 55
src/client/styles/scss/_login.scss

@@ -1,12 +1,4 @@
 .nologin {
 .nologin {
-  $gray-800-for-login: darken(white, 30%);
-  $color-gradient: #3e4d6c;
-
-  // background color
-  background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
-    linear-gradient(135deg, $growi-green 10%, hsla(225, 95%, 50%, 0) 70%), linear-gradient(225deg, $growi-blue 10%, hsla(140, 90%, 50%, 0) 80%),
-    linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
-
   #page-wrapper {
   #page-wrapper {
     background: none;
     background: none;
   }
   }
@@ -62,43 +54,20 @@
 
 
   // styles
   // styles
   .login-header {
   .login-header {
-    background-color: rgba(white, 0.5);
-
-    .logo {
-      background-color: rgba(black, 0);
-      fill: rgba(black, 0.5);
-    }
-
     h1 {
     h1 {
       font-size: 22px;
       font-size: 22px;
       line-height: 1em;
       line-height: 1em;
-      color: rgba(black, 0.5);
     }
     }
   }
   }
 
 
-  .login-dialog {
-    background-color: rgba(white, 0.5);
-  }
-
   .input-group {
   .input-group {
     margin-bottom: 10px;
     margin-bottom: 10px;
 
 
     .input-group-text {
     .input-group-text {
-      color: $gray-800-for-login;
       text-align: center;
       text-align: center;
-      background-color: rgba(black, 0.4);
       border: none;
       border: none;
       border-radius: 0;
       border-radius: 0;
     }
     }
-
-    .form-control {
-      color: white;
-      background-color: rgba(lighten(black, 10%), 0.4);
-
-      &::placeholder {
-        color: $gray-800-for-login;
-      }
-    }
   }
   }
 
 
   .input-group:not(.has-error) {
   .input-group:not(.has-error) {
@@ -114,39 +83,39 @@
   $btn-fill-colors: (
   $btn-fill-colors: (
     'login': (
     'login': (
       rgba($danger, 0.4),
       rgba($danger, 0.4),
-      rgba(#7e4153, 0.5),
+      rgba(#7e4153, 0.7),
     ),
     ),
     'register': (
     'register': (
       rgba($success, 0.4),
       rgba($success, 0.4),
-      rgba(#3f7263, 0.5),
+      rgba(#3f7263, 0.7),
     ),
     ),
     'google': (
     'google': (
       rgba(#24292e, 0.4),
       rgba(#24292e, 0.4),
-      #555,
+      #444,
     ),
     ),
     'github': (
     'github': (
       rgba(lighten(black, 20%), 0.4),
       rgba(lighten(black, 20%), 0.4),
-      #555,
+      #444,
     ),
     ),
     'facebook': (
     'facebook': (
       rgba(#29487d, 0.4),
       rgba(#29487d, 0.4),
-      #555,
+      #444,
     ),
     ),
     'twitter': (
     'twitter': (
       rgba(#1da1f2, 0.4),
       rgba(#1da1f2, 0.4),
-      #555,
+      #444,
     ),
     ),
     'oidc': (
     'oidc': (
       rgba(#24292e, 0.4),
       rgba(#24292e, 0.4),
-      #555,
+      #444,
     ),
     ),
     'saml': (
     'saml': (
       rgba(#55a79a, 0.4),
       rgba(#55a79a, 0.4),
-      #555,
+      #444,
     ),
     ),
     'basic': (
     'basic': (
       rgba(#24292e, 0.4),
       rgba(#24292e, 0.4),
-      #555,
+      #444,
     ),
     ),
   );
   );
 
 
@@ -165,26 +134,12 @@
   .link-growi-org {
   .link-growi-org {
     font-size: smaller;
     font-size: smaller;
     font-weight: bold;
     font-weight: bold;
-    color: rgba(black, 0.4);
 
 
     &,
     &,
     .growi,
     .growi,
     .org {
     .org {
       transition: color 0.8s;
       transition: color 0.8s;
     }
     }
-
-    &:hover,
-    &.focus {
-      color: black;
-
-      .growi {
-        color: darken($growi-green, 20%);
-      }
-
-      .org {
-        color: darken($growi-blue, 15%);
-      }
-    }
   }
   }
 
 
   .link-switch {
   .link-switch {
@@ -210,7 +165,7 @@
   .link-growi-org {
   .link-growi-org {
     position: absolute;
     position: absolute;
     bottom: 9px;
     bottom: 9px;
-    z-index: 2;
+    z-index: 3;
   }
   }
 
 
   // To adjust the behavior, this problem is not solved.
   // To adjust the behavior, this problem is not solved.

+ 3 - 0
src/client/styles/scss/_navbar.scss

@@ -1,5 +1,8 @@
 .grw-navbar {
 .grw-navbar {
+  border-top: 0;
+  border-right: 0;
   border-bottom: $grw-navbar-border-width solid;
   border-bottom: $grw-navbar-border-width solid;
+  border-left: 0;
 
 
   .grw-navbar-toggler {
   .grw-navbar-toggler {
     padding: 0.5rem;
     padding: 0.5rem;

+ 4 - 10
src/client/styles/scss/_on-edit.scss

@@ -26,8 +26,10 @@ body.on-edit {
   }
   }
 
 
   // show
   // show
-  .d-edit-block {
-    display: block !important;
+  .d-edit-sm-block {
+    @include media-breakpoint-up(sm) {
+      display: block !important;
+    }
   }
   }
 
 
   // hide unnecessary elements
   // hide unnecessary elements
@@ -134,14 +136,6 @@ body.on-edit {
     }
     }
   }
   }
 
 
-  // deal with word wrap problem
-  // see: https://qiita.com/mpyw/items/dfc63c1fed5dfc5eda26
-  .page-editor-editor-container,
-  .page-editor-preview-container {
-    min-width: 0;
-    overflow-wrap: break-word;
-  }
-
   /*********************
   /*********************
    * Navigation styles
    * Navigation styles
    */
    */

+ 5 - 0
src/client/styles/scss/_override-bootstrap.scss

@@ -130,4 +130,9 @@
     margin-bottom: 18px;
     margin-bottom: 18px;
     overflow: hidden;
     overflow: hidden;
   }
   }
+
+  .text-break {
+    word-break: break-word;
+    overflow-wrap: break-word;
+  }
 }
 }

+ 57 - 3
src/client/styles/scss/_search.scss

@@ -66,13 +66,22 @@
     border-bottom-left-radius: 40px;
     border-bottom-left-radius: 40px;
   }
   }
 
 
+  .search-typeahead {
+    // corner radius
+    border-top-right-radius: 40px;
+    border-bottom-right-radius: 40px;
+    .rbt-input-main {
+      padding-right: 58px;
+      // corner radius
+      border-top-right-radius: 40px;
+      border-bottom-right-radius: 40px;
+    }
+  }
+
   // using react-bootstrap-typeahead
   // using react-bootstrap-typeahead
   // see: https://github.com/ericgio/react-bootstrap-typeahead
   // see: https://github.com/ericgio/react-bootstrap-typeahead
   .rbt-input.form-control {
   .rbt-input.form-control {
     height: 30px;
     height: 30px;
-    border-top-right-radius: 40px;
-    border-bottom-right-radius: 40px;
-
     .rbt-input-wrapper {
     .rbt-input-wrapper {
       margin-left: 8px;
       margin-left: 8px;
     }
     }
@@ -120,6 +129,22 @@
       @include media-breakpoint-up(md) {
       @include media-breakpoint-up(md) {
         width: 300px;
         width: 300px;
       }
       }
+      @include media-breakpoint-up(lg) {
+        // focus
+        &.focus {
+          width: 400px;
+        }
+      }
+      @include media-breakpoint-up(xl) {
+        width: 350px;
+        // focus
+        &.focus {
+          width: 450px;
+        }
+      }
+    }
+    .search-typeahead {
+      border-radius: 0 25px 25px 0;
     }
     }
   }
   }
 }
 }
@@ -210,3 +235,32 @@
     display: table-header-group;
     display: table-header-group;
   }
   }
 }
 }
+
+@include media-breakpoint-down(sm) {
+  .grw-search-table {
+    th {
+      text-align: right;
+    }
+  
+    td {
+      overflow-wrap: anywhere;
+      white-space: normal !important;
+    }
+  
+    @include media-breakpoint-down(xs) {
+      th,
+      td {
+        display: block;
+      }
+      
+      th {
+        text-align: left;
+      }
+      
+      td {
+        border-top: none !important;
+        padding-top: 0 !important;
+      }
+    }
+  }
+}

+ 1 - 1
src/client/styles/scss/atoms/_buttons.scss

@@ -41,7 +41,7 @@
   color: white;
   color: white;
   text-align: center;
   text-align: center;
   cursor: pointer;
   cursor: pointer;
-  background-color: rgba(lighten(black, 20%), 0.4);
+  background-color: rgba(lighten(black, 15%), 0.5);
   border: none;
   border: none;
 
 
   .btn-label {
   .btn-label {

+ 31 - 0
src/client/styles/scss/atoms/_custom_control.scss

@@ -1,3 +1,34 @@
 label.custom-control-label {
 label.custom-control-label {
   font-weight: normal;
   font-weight: normal;
 }
 }
+
+.custom-switch.custom-switch-sm {
+  $custom-control-indicator-size-sm: $custom-control-indicator-size * 0.8;
+  $custom-switch-width-sm: $custom-control-indicator-size-sm * 1.75;
+  $custom-control-gutter-sm: $custom-control-gutter * 0.8;
+  $custom-control-indicator-size-sm: $custom-control-indicator-size * 0.8;
+  $custom-switch-indicator-size-sm: subtract($custom-control-indicator-size-sm, $custom-control-indicator-border-width * 4);
+
+  padding-left: $custom-switch-width-sm + $custom-control-gutter-sm;
+
+  .custom-control-label {
+    &::before {
+      left: -($custom-switch-width-sm + $custom-control-gutter-sm);
+      width: $custom-switch-width-sm;
+      height: $custom-control-indicator-size-sm;
+    }
+
+    &::after {
+      top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);
+      left: add(-($custom-switch-width-sm + $custom-control-gutter-sm), $custom-control-indicator-border-width * 2);
+      width: $custom-switch-indicator-size-sm;
+      height: $custom-switch-indicator-size-sm;
+    }
+  }
+
+  .custom-control-input:checked ~ .custom-control-label {
+    &::after {
+      transform: translateX($custom-switch-width-sm - $custom-control-indicator-size-sm);
+    }
+  }
+}

+ 3 - 0
src/client/styles/scss/atoms/_nav.scss

@@ -1,6 +1,9 @@
 .nav-tabs .grw-main-nav-item-left {
 .nav-tabs .grw-main-nav-item-left {
   width: $grw-nav-main-left-tab-width;
   width: $grw-nav-main-left-tab-width;
   text-align: center;
   text-align: center;
+  @include media-breakpoint-down(xs) {
+    width: 45px;
+  }
 
 
   .nav-link {
   .nav-link {
     padding-right: 0;
     padding-right: 0;

+ 8 - 0
src/client/styles/scss/style-app.scss

@@ -75,6 +75,14 @@
  * Helper Classes
  * Helper Classes
  */
  */
 
 
+.mw-0 {
+  min-width: 0;
+}
+
+.flex-basis-0 {
+  flex-basis: 0;
+}
+
 .picture {
 .picture {
   width: 24px;
   width: 24px;
   height: 24px;
   height: 24px;

+ 81 - 0
src/client/styles/scss/theme/_apply-colors-dark.scss

@@ -94,6 +94,87 @@ ul.pagination {
   }
   }
 }
 }
 
 
+/*
+ * GROWI Login form
+ */
+.nologin {
+  // background color
+  $color-gradient: #3c465c;
+  background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
+    linear-gradient(135deg, darken($growi-green, 30%) 10%, hsla(225, 95%, 50%, 0) 70%),
+    linear-gradient(225deg, darken($growi-blue, 20%) 10%, hsla(140, 90%, 50%, 0) 80%),
+    linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
+
+  .login-header {
+    background-color: rgba(black, 0.5);
+
+    .logo {
+      background-color: rgba(white, 0);
+      fill: rgba(white, 0.5);
+    }
+
+    h1 {
+      color: rgba(white, 0.5);
+    }
+  }
+
+  .login-dialog {
+    background-color: rgba(black, 0.5);
+  }
+
+  .input-group {
+    .input-group-text {
+      color: darken(white, 30%);
+      background-color: rgba(#444, 0.7);
+    }
+
+    .form-control {
+      color: white;
+      background-color: rgba(#505050, 0.7);
+      box-shadow: unset;
+
+      &::placeholder {
+        color: darken(white, 30%);
+      }
+    }
+  }
+
+  .btn-fill {
+    .btn-label {
+      color: #ccc;
+    }
+    .btn-label-text {
+      color: #aaa;
+    }
+  }
+
+  .grw-external-auth-form {
+    border-color: gray !important;
+  }
+
+  .btn-external-auth-tab {
+    @extend .btn-dark;
+  }
+
+  // footer link text
+  .link-growi-org {
+    color: rgba(white, 0.4);
+
+    &:hover,
+    &.focus {
+      color: rgba(white, 0.7);
+
+      .growi {
+        color: darken($growi-green, 5%);
+      }
+
+      .org {
+        color: darken($growi-blue, 5%);
+      }
+    }
+  }
+}
+
 /*
 /*
  * GROWI page list
  * GROWI page list
  */
  */

+ 57 - 6
src/client/styles/scss/theme/_apply-colors-light.scss

@@ -39,14 +39,65 @@ $table-hover-bg: $bgcolor-table-hover;
 }
 }
 
 
 /*
 /*
- * GROWI search-top
+ * GROWI Login form
  */
  */
-.search-top {
-  .btn-group-dropdown-scope .dropdown-toggle {
-    background-color: rgba($bgcolor-global, 0.8);
+.nologin {
+  // background color
+  $color-gradient: #3e4d6c;
+  background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
+    linear-gradient(135deg, $growi-green 10%, hsla(225, 95%, 50%, 0) 70%), linear-gradient(225deg, $growi-blue 10%, hsla(140, 90%, 50%, 0) 80%),
+    linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
+
+  .login-header {
+    background-color: rgba(white, 0.5);
+
+    .logo {
+      background-color: rgba(black, 0);
+      fill: rgba(black, 0.5);
+    }
+
+    h1 {
+      color: rgba(black, 0.5);
+    }
   }
   }
-  .rbt-input.form-control {
-    background-color: rgba($bgcolor-global, 0.9);
+
+  .login-dialog {
+    background-color: rgba(white, 0.5);
+  }
+
+  .input-group {
+    .input-group-text {
+      color: darken(white, 30%);
+      background-color: rgba(#444, 0.7);
+    }
+
+    .form-control {
+      color: white;
+      background-color: rgba(#505050, 0.7);
+      box-shadow: unset;
+
+      &::placeholder {
+        color: darken(white, 30%);
+      }
+    }
+  }
+
+  // footer link text
+  .link-growi-org {
+    color: rgba(black, 0.4);
+
+    &:hover,
+    &.focus {
+      color: black;
+
+      .growi {
+        color: darken($growi-green, 20%);
+      }
+
+      .org {
+        color: darken($growi-blue, 15%);
+      }
+    }
   }
   }
 }
 }
 
 

+ 5 - 0
src/client/styles/scss/theme/_apply-colors.scss

@@ -154,6 +154,11 @@ pre:not(.hljs):not(.CodeMirror-line) {
   .btn-secondary.dropdown-toggle {
   .btn-secondary.dropdown-toggle {
     @include button-variant($bgcolor-search-top-dropdown, $bgcolor-search-top-dropdown);
     @include button-variant($bgcolor-search-top-dropdown, $bgcolor-search-top-dropdown);
   }
   }
+
+  // for https://youtrack.weseek.co.jp/issue/GW-2603
+  .search-typeahead {
+    background-color: rgba($bgcolor-global, 0.9);
+  }
 }
 }
 
 
 .grw-sidebar {
 .grw-sidebar {

+ 10 - 3
src/client/styles/scss/theme/antarctic.scss

@@ -123,9 +123,16 @@ html[dark] {
     }
     }
   }
   }
 
 
-  a#login.link-switch,
-  a#register.link-switch {
-    color: rgba(black, 0.5);
+  // login and register
+  .nologin {
+    a#login.link-switch,
+    a#register.link-switch {
+      color: rgba(black, 0.5);
+    }
+
+    .grw-external-auth-form {
+      border-color: #aaa !important;
+    }
   }
   }
 }
 }
 
 

+ 15 - 11
src/client/styles/scss/theme/christmas.scss

@@ -135,22 +135,26 @@ html[dark] {
   // login page
   // login page
   .nologin {
   .nologin {
     .input-group {
     .input-group {
-      .input-group-addon {
-        background-color: rgba(lighten(black, 10%), 0.6);
+      .input-group-text {
+        color: #444;
+        background-color: rgba(darken(white, 20%), 0.6);
       }
       }
       .form-control {
       .form-control {
-        background-color: rgba(lighten(black, 10%), 0.6);
+        color: #444;
+        background-color: rgba(white, 0.6);
       }
       }
     }
     }
 
 
-    &.login-page {
-      .login-header,
-      .login-dialog {
-        background-color: rgba(#ccc, 0.5);
-      }
-      .link-switch {
-        color: #bd3425;
-      }
+    .login-header,
+    .login-dialog {
+      background-color: rgba(#ccc, 0.5);
+    }
+    .link-switch {
+      color: #bd3425;
+    }
+
+    .grw-external-auth-form {
+      border-color: #aaa !important;
     }
     }
   }
   }
 
 

+ 14 - 5
src/client/styles/scss/theme/spring.scss

@@ -104,7 +104,8 @@ html[dark] {
     }
     }
   }
   }
 
 
-  .growi.login-page {
+  // login and register
+  .nologin {
     #page-wrapper {
     #page-wrapper {
       background-color: $themelight;
       background-color: $themelight;
       background-image: url('/images/themes/spring/spring.svg');
       background-image: url('/images/themes/spring/spring.svg');
@@ -112,11 +113,19 @@ html[dark] {
       background-position: bottom;
       background-position: bottom;
       background-size: cover;
       background-size: cover;
     }
     }
-  }
 
 
-  a#login.link-switch,
-  a#register.link-switch {
-    color: $color-global;
+    .login-header,
+    .login-dialog {
+      background-color: rgba(black, 0.1);
+    }
+
+    .link-switch {
+      color: $color-global;
+    }
+
+    .grw-external-auth-form {
+      border-color: $accentcolor !important;
+    }
   }
   }
 
 
   .table {
   .table {

+ 13 - 7
src/client/styles/scss/theme/wood.scss

@@ -144,14 +144,20 @@ html[dark] {
   }
   }
 
 
   // login and register
   // login and register
+  .nologin {
+    background: white;
 
 
-  .login-header,
-  .login-dialog {
-    background-color: rgba(black, 0.1);
-  }
+    .login-header,
+    .login-dialog {
+      background-color: rgba(black, 0.1);
+    }
 
 
-  a#login.link-switch,
-  a#register.link-switch {
-    color: rgba(black, 0.5);
+    .link-switch {
+      color: rgba(black, 0.5);
+    }
+
+    .grw-external-auth-form {
+      border-color: #aaa !important;
+    }
   }
   }
 }
 }

+ 1 - 1
src/lib/components/PagePathHierarchicalLink.jsx

@@ -46,7 +46,7 @@ const PagePathHierarchicalLink = (props) => {
   const RootElm = ({ children }) => {
   const RootElm = ({ children }) => {
     return props.isInnerElem
     return props.isInnerElem
       ? <>{children}</>
       ? <>{children}</>
-      : <span className="grw-page-path-hierarchical-link">{children}</span>;
+      : <span className="grw-page-path-hierarchical-link text-break">{children}</span>;
   };
   };
 
 
   return (
   return (

+ 8 - 12
src/server/views/layout-growi/base/layout.html

@@ -15,20 +15,16 @@
 </header>
 </header>
 {% endblock %}
 {% endblock %}
 
 
-<div class="container-fluid">
-  <div class="row">
-    <div id="main" class="main col-md-12 {% if page %}{{ css.grant(page) }}{% endif %} {% block main_css_class %}{% endblock %}">
-      {% block content_main_before %}
-      {% endblock %}
+<div id="main" class="main container-fluid {% if page %}{{ css.grant(page) }}{% endif %} {% block main_css_class %}{% endblock %}">
+  {% block content_main_before %}
+  {% endblock %}
 
 
-      {% block content_main %}
-      {% endblock content_main %}
+  {% block content_main %}
+  {% endblock content_main %}
 
 
-      {% block content_main_after %}
-      {% endblock %}
-    </div><!-- /.main -->
-  </div><!-- /.row -->
-</div><!-- /.container-fluid -->
+  {% block content_main_after %}
+  {% endblock %}
+</div><!-- /.main -->
 
 
 <footer class="footer">
 <footer class="footer">
   {% include '../../widget/system-version.html' %}
   {% include '../../widget/system-version.html' %}

+ 6 - 8
src/server/views/layout-growi/widget/liker-and-seenusers.html

@@ -1,16 +1,14 @@
 <div class="liker-and-seenusers">
 <div class="liker-and-seenusers">
-  <div class="text-right">
-    {% if page.liker.length > 10 %}<span class="text-muted">..</span>{% endif %}
-    <span id="liker-list" class="mr-3" data-user-ids="{{ page.liker|slice(-9)|default([])|join(',') }}"></span>
+  <div class="text-truncate text-muted text-right" style="direction: rtl;">
     <span class="text-info">
     <span class="text-info">
-      <i class="icon-fw icon-like"></i><span class="liker-user-count">{{ page.liker.length|default(0) }}</span>
+      <span class="liker-user-count">{{ page.liker.length|default(0) }}</span><i class="icon-fw icon-like"></i>
     </span>
     </span>
+    <span id="liker-list" class="mr-1" data-user-ids="{{ page.liker|slice(-15)|default([])|reverse|join(',') }}"></span>
   </div>
   </div>
-  <div class="text-right">
-    {% if page.seenUsers.length > 10 %}<span class="text-muted">..</span>{% endif %}
-    <span id="seen-user-list" class="mr-3" data-user-ids="{{ page.seenUsers|slice(-9)|default([])|join(',') }}"></span>
+  <div class="text-truncate text-muted text-right" style="direction: rtl;">
     <span class="text-danger">
     <span class="text-danger">
-      <i class="icon-fw fa fa-paw"></i><span class="seen-user-count">{{ page.seenUsers.length|default(0) }}</span>
+      <span class="seen-user-count">{{ page.seenUsers.length|default(0) }}</span><i class="fa fa-fw fa-paw"></i>
     </span>
     </span>
+    <span id="seen-user-list" class="mr-1" data-user-ids="{{ page.seenUsers|slice(-15)|default([])|reverse|join(',') }}"></span>
   </div>
   </div>
 </div>
 </div>

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

@@ -118,7 +118,7 @@
     {# Sidebar #}
     {# Sidebar #}
     <div id="grw-sidebar-wrapper"></div>
     <div id="grw-sidebar-wrapper"></div>
 
 
-    <div class="flex-grow-1">
+    <div class="flex-fill mw-0">
       {% block head_warn_alert_siteurl_undefined %}{% include '../widget/alert_siteurl_undefined.html' %}{% endblock %}
       {% block head_warn_alert_siteurl_undefined %}{% include '../widget/alert_siteurl_undefined.html' %}{% endblock %}
 
 
       {# Search #}
       {# Search #}

+ 3 - 3
src/server/views/login/error.html

@@ -2,7 +2,7 @@
 
 
 {% block html_base_css %}error nologin{% endblock %}
 {% block html_base_css %}error nologin{% endblock %}
 
 
-{% block html_title %}{{ customizeService.generateCustomTitleForFixedPageName('セットアップ') }}{% endblock %}
+{% block html_title %}{{ customizeService.generateCustomTitleForFixedPageName(t('login.Setup')) }}{% endblock %}
 
 
 
 
 
 
@@ -33,11 +33,11 @@
       <div class="mb-4 login-form-errors text-center">
       <div class="mb-4 login-form-errors text-center">
         {% if reason === 'registered'%}
         {% if reason === 'registered'%}
         <div class="alert alert-success">
         <div class="alert alert-success">
-          <h2>登録完了</h2>
+          <h2>{{ t('login.Registration successful') }}</h2>
         </div>
         </div>
         {% else %}
         {% else %}
         <div class="alert alert-warning">
         <div class="alert alert-warning">
-            <h2>ログインエラー</h2>
+            <h2>{{ t('login.Sign in error') }}</h2>
         </div>
         </div>
         {% endif %}
         {% endif %}
       </div>
       </div>

+ 1 - 1
src/server/views/widget/not_found_tabs.html

@@ -15,6 +15,6 @@
     </a>
     </a>
   </li>
   </li>
 
 
-  <div id="page-editor-path-nav" class="d-none d-edit-block ml-2"></div>
+  <div id="page-editor-path-nav" class="d-none d-edit-sm-block ml-2"></div>
   {% endif %}
   {% endif %}
 </ul>
 </ul>

+ 6 - 6
src/server/views/widget/page_tabs.html

@@ -6,7 +6,7 @@
   #}
   #}
   <li class="nav-item grw-main-nav-item-left">
   <li class="nav-item grw-main-nav-item-left">
     <a class="nav-link active" href="#revision-body" role="tab" data-toggle="tab">
     <a class="nav-link active" href="#revision-body" role="tab" data-toggle="tab">
-      <i class="icon-control-play"></i> View
+      <i class="icon-control-play icon-fw"></i><span class="d-none d-sm-inline">View</span>
     </a>
     </a>
   </li>
   </li>
 
 
@@ -19,7 +19,7 @@
           data-toggle="tooltip" data-placement="top" data-container="body" title="{{ t('Not available for guest') }}"
           data-toggle="tooltip" data-placement="top" data-container="body" title="{{ t('Not available for guest') }}"
         {% endif %}
         {% endif %}
       >
       >
-        <i class="icon-note"></i> {{ t('Edit') }}
+        <i class="icon-note icon-fw"></i><span class="d-none d-sm-inline">{{ t('Edit') }}</span>
       </a>
       </a>
     </li>
     </li>
 
 
@@ -32,12 +32,12 @@
           data-toggle="tooltip" data-placement="top" data-container="body" title="{{ t('Not available for guest') }}"
           data-toggle="tooltip" data-placement="top" data-container="body" title="{{ t('Not available for guest') }}"
         {% endif %}
         {% endif %}
       >
       >
-        <i class="fa fa-file-text-o"></i> {{ t('HackMD') }}
+        <i class="fa fa-fw fa-file-text-o"></i><span class="d-none d-sm-inline">{{ t('HackMD') }}</span>
       </a>
       </a>
     </li>
     </li>
     {% endif %}
     {% endif %}
 
 
-    <div id="page-editor-path-nav" class="d-none d-edit-block ml-2"></div>
+    <div id="page-editor-path-nav" class="d-none d-edit-sm-block ml-2"></div>
   {% endif %}
   {% endif %}
 
 
   {#
   {#
@@ -51,7 +51,7 @@
   {% if not page.isTopPage() %}
   {% if not page.isTopPage() %}
     <li class="nav-item">
     <li class="nav-item">
       <a href="?presentation=1" class="nav-link toggle-presentation">
       <a href="?presentation=1" class="nav-link toggle-presentation">
-        <i class="icon-film"></i><span class="d-none d-md-inline"> {{ t('Presentation Mode') }}</span>
+        <i class="icon-film icon-fw"></i><span class="d-none d-md-inline">{{ t('Presentation Mode') }}</span>
       </a>
       </a>
     </li>
     </li>
   {% endif %}
   {% endif %}
@@ -59,7 +59,7 @@
   <!-- revision-history -->
   <!-- revision-history -->
   <li class="nav-item">
   <li class="nav-item">
     <a class="nav-link" href="#revision-history" role="tab" data-toggle="tab">
     <a class="nav-link" href="#revision-history" role="tab" data-toggle="tab">
-      <i class="icon-layers"></i><span class="d-none d-md-inline"> {{ t('History') }}</span>
+      <i class="icon-layers icon-fw"></i><span class="d-none d-md-inline">{{ t('History') }}</span>
     </a>
     </a>
   </li>
   </li>
 
 

+ 1 - 1
src/server/views/widget/page_tabs_kibela.html

@@ -36,7 +36,7 @@
     </li>
     </li>
     {% endif %}
     {% endif %}
 
 
-    <div id="page-editor-path-nav" class="d-none d-edit-block ml-2"></div>
+    <div id="page-editor-path-nav" class="d-none d-edit-sm-block ml-2"></div>
 
 
   {% endif %}
   {% endif %}
 
 

+ 12 - 4
src/server/views/widget/user_page_content.html

@@ -2,20 +2,28 @@
   <ul class="nav nav-tabs user-page-content-menu mb-4" role="tablist">
   <ul class="nav nav-tabs user-page-content-menu mb-4" role="tablist">
     <li class="nav-item">
     <li class="nav-item">
       <a class="nav-link active" href="#user-bookmark-list" role="tab" data-toggle="tab">
       <a class="nav-link active" href="#user-bookmark-list" role="tab" data-toggle="tab">
-        <i class="icon-star"></i> Bookmarks
+        <i class="icon-star"></i>
+        <span class="d-none d-sm-inline">Bookmarks</span>
       </a>
       </a>
     </li>
     </li>
     <li class="nav-item">
     <li class="nav-item">
       <a class="nav-link" href="#user-created-list" role="tab" data-toggle="tab">
       <a class="nav-link" href="#user-created-list" role="tab" data-toggle="tab">
-        <i class="icon-clock"></i> Recently Created
+        <i class="icon-clock"></i>
+        <span class="d-none d-sm-inline">Recently Created</span>
       </a>
       </a>
     </li>
     </li>
     <li class="nav-item">
     <li class="nav-item">
-      <a class="nav-link" href="#user-draft-list" role="tab" data-toggle="tab"><i class="icon-docs"></i> My Drafts</a>
+      <a class="nav-link" href="#user-draft-list" role="tab" data-toggle="tab">
+        <i class="icon-docs"></i>
+        <span class="d-none d-sm-inline">My Drafts</span>
+      </a>
     </li>
     </li>
     {% if user._id.toString() == pageUser._id.toString() %}
     {% if user._id.toString() == pageUser._id.toString() %}
     <li class="nav-item">
     <li class="nav-item">
-      <a class="nav-link" href="/me" role="tab"><i class="icon-wrench"></i> Settings</a>
+      <a class="nav-link" href="/me" role="tab">
+        <i class="icon-wrench"></i>
+        <span class="d-none d-sm-inline">Settings</span>
+      </a>
     </li>
     </li>
     {% endif %}
     {% endif %}
   </ul>
   </ul>