Преглед на файлове

Merge commit 'a3de680ff2464cb28209a8622c7e01a94a3e37ea' into support/bstr4-create-template-modal

yusuketk преди 6 години
родител
ревизия
7e936b67ff

+ 13 - 11
src/client/js/components/Admin/Common/AdminNavigation.jsx

@@ -13,40 +13,42 @@ const AdminNavigation = (props) => {
 
   return (
     <div className="list-group admin-navigation">
-      <a href="/admin" className={`list-group-item list-group-item-action border-0 ${pathname === '/admin' && 'active'}`}>
+      <a href="/admin" className={`list-group-item list-group-item-action border-0 round-corner ${pathname === '/admin' && 'active'}`}>
         <i className="icon-fw icon-home"></i> {t('Management Wiki Home')}
       </a>
-      <a href="/admin/app" className={`list-group-item list-group-item-action border-0 ${isActiveMenu('/app') && 'active'}`}>
+      <a href="/admin/app" className={`list-group-item list-group-item-action border-0 round-corner ${isActiveMenu('/app') && 'active'}`}>
         <i className="icon-fw icon-settings"></i> {t('App Settings')}
       </a>
-      <a href="/admin/security" className={`list-group-item list-group-item-action border-0  ${isActiveMenu('/security') && 'active'}`}>
+      <a href="/admin/security" className={`list-group-item list-group-item-action border-0 round-corner  ${isActiveMenu('/security') && 'active'}`}>
         <i className="icon-fw icon-shield"></i> {t('security_settings')}
       </a>
-      <a href="/admin/markdown" className={`list-group-item list-group-item-action border-0 ${isActiveMenu('/markdown') && 'active'}`}>
+      <a href="/admin/markdown" className={`list-group-item list-group-item-action border-0 round-corner ${isActiveMenu('/markdown') && 'active'}`}>
         <i className="icon-fw icon-note"></i> {t('Markdown Settings')}
       </a>
-      <a href="/admin/customize" className={`list-group-item list-group-item-action border-0 ${isActiveMenu('/customize') && 'active'}`}>
+      <a href="/admin/customize" className={`list-group-item list-group-item-action border-0 round-corner ${isActiveMenu('/customize') && 'active'}`}>
         <i className="icon-fw icon-wrench"></i> {t('Customize')}
       </a>
-      <a href="/admin/importer" className={`list-group-item list-group-item-action border-0 ${isActiveMenu('/importer') && 'active'}`}>
+      <a href="/admin/importer" className={`list-group-item list-group-item-action border-0 round-corner ${isActiveMenu('/importer') && 'active'}`}>
         <i className="icon-fw icon-cloud-upload"></i> {t('Import Data')}
       </a>
-      <a href="/admin/export" className={`list-group-item list-group-item-action border-0 ${isActiveMenu('/export') && 'active'}`}>
+      <a href="/admin/export" className={`list-group-item list-group-item-action border-0 round-corner ${isActiveMenu('/export') && 'active'}`}>
         <i className="icon-fw icon-cloud-download"></i> {t('Export Archive Data')}
       </a>
       <a
         href="/admin/notification"
-        className={`list-group-item list-group-item-action  border-0 ${(isActiveMenu('/notification') || isActiveMenu('/global-notification')) && 'active'}`}
+        className={
+          `list-group-item list-group-item-action border-0 round-corner ${(isActiveMenu('/notification') || isActiveMenu('/global-notification')) && 'active'}`
+        }
       >
         <i className="icon-fw icon-bell"></i> {t('Notification Settings')}
       </a>
-      <a href="/admin/users" className={`list-group-item list-group-item-action border-0 ${(isActiveMenu('/users')) && 'active'}`}>
+      <a href="/admin/users" className={`list-group-item list-group-item-action border-0 round-corner ${(isActiveMenu('/users')) && 'active'}`}>
         <i className="icon-fw icon-user"></i> {t('User_Management')}
       </a>
-      <a href="/admin/user-groups" className={`list-group-item list-group-item-action border-0 ${isActiveMenu('/user-group') && 'active'}`}>
+      <a href="/admin/user-groups" className={`list-group-item list-group-item-action border-0 round-corner ${isActiveMenu('/user-group') && 'active'}`}>
         <i className="icon-fw icon-people"></i> {t('UserGroup Management')}
       </a>
-      <a href="/admin/search" className={`list-group-item list-group-item-action border-0 ${isActiveMenu('/search') && 'active'}`}>
+      <a href="/admin/search" className={`list-group-item list-group-item-action border-0 round-corner ${isActiveMenu('/search') && 'active'}`}>
         <i className="icon-fw icon-magnifier"></i> {t('Full Text Search Management')}
       </a>
     </div>

+ 35 - 14
src/client/styles/scss/_layout_kibela.scss

@@ -119,6 +119,24 @@ body.kibela {
     }
   }
 
+  /* admin navigation */
+  .admin-navigation {
+    .list-group-item + .list-group-item.active {
+      margin-top: 2px;
+    }
+
+    .list-group-item.active {
+      color: #fff;
+      background: #1256a3;
+    }
+
+    .list-group-item {
+      &:hover {
+        background: #eee;
+      }
+    }
+  }
+
   /* search page */
   .search-result-list,
   .page-list-li {
@@ -127,25 +145,28 @@ body.kibela {
 
   /* Tabs */
   .nav.nav-tabs {
-    border-bottom-color: #f4f5f6;
+    > .nav-item {
+      color: #5882fa;
+      cursor: pointer;
+      background: transparent;
 
-    > li > a {
-      &,
       &:hover,
       &:focus {
-        background: transparent;
-        border-top: none;
-        border-right: none;
-        border-left: none;
+        > .nav-link {
+          color: #7a94d9;
+        }
       }
-    }
 
-    > li.active > a {
-      background: transparent !important;
-      border-top: none;
-      border-right: none;
-      border-bottom: solid 2.7px #5584e1;
-      border-left: none;
+      > .nav-link {
+        color: #5882fa;
+        border: none;
+        border-radius: 3px;
+      }
+
+      > .nav-link.active {
+        background: transparent !important;
+        border-bottom: solid 2.7px #5584e1;
+      }
     }
 
     .wiki {

+ 141 - 47
src/client/styles/scss/_login.scss

@@ -5,6 +5,7 @@
   background: linear-gradient(45deg, darken($inverse, 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($inverse, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
+
   #page-wrapper {
     background: none;
   }
@@ -47,25 +48,32 @@
             }
           }
         }
-      } // .main
-    } // #page-wrapper
-  } // #wrapper
+      }
+
+      // .main
+    }
+
+    // #page-wrapper
+  }
+
+  // #wrapper
 
   // styles
   .login-header {
     background-color: rgba(white, 0.5);
+
     .logo {
-      .group1,
-      .group2 {
-        fill: rgba(black, 0.5);
-      }
+      background-color: rgba(black, 0);
+      fill: rgba(black, 0.5);
     }
+
     h1 {
       font-size: 22px;
       line-height: 1em;
       color: rgba(black, 0.5);
     }
   }
+
   .login-dialog {
     background-color: rgba(white, 0.5);
   }
@@ -73,21 +81,24 @@
   .input-group {
     margin-bottom: 10px;
 
-    .input-group-addon {
+    .input-group-text {
       color: $gray-800-for-login;
       text-align: center;
       background-color: rgba(black, 0.4);
       border: none;
       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) {
     .form-control {
       border: transparent;
@@ -97,10 +108,12 @@
   .external-auth {
     form {
       flex: 1;
+
       @media (min-width: 350px) {
         flex: 0.49;
       }
     }
+
     .spacer {
       height: 10px;
     }
@@ -108,6 +121,7 @@
 
   .collapse-external-auth {
     overflow: hidden;
+
     &:not(.in) {
       height: 0;
       padding: 0 !important;
@@ -115,92 +129,160 @@
   }
 
   // button style
-  .btn-login.fcbtn,
-  .btn-register.fcbtn,
-  .btn-login-oauth.fcbtn,
-  .btn-collapse-external-auth {
+
+  .fcbtn {
+    position: relative;
+    overflow: hidden;
     color: white;
+    text-align: center;
+    cursor: pointer;
     background-color: rgba(lighten(black, 20%), 0.4);
     border: none;
 
     .btn-label {
-      padding: 9px 15px;
-      margin: -8px 20px -8px -20px;
-    }
-    &:focus {
-      border: none;
+      position: relative;
+      z-index: 1;
+      color: white;
+      text-decoration: none;
     }
-  }
-  .btn-login-oauth {
-    flex: 1;
+
     .btn-label-text {
-      flex: 1;
+      position: relative;
+      z-index: 1;
+      color: white;
+      text-decoration: none;
+    }
+
+    // effect
+    .eff {
+      position: absolute;
+      top: -50px;
+      left: 0px;
+      z-index: 0;
+      width: 100%;
+      height: 100%;
+      transition: all 0.5s ease;
+    }
+
+    &:hover {
+      .eff {
+        top: 0;
+      }
     }
   }
-  .btn-login.fcbtn {
+
+  // login
+  .fcbtn.login {
     .btn-label {
       background-color: rgba($danger, 0.4);
     }
-    &:after {
-      background-color: #7e4153;
+    .eff {
+      background-color: rgba(#7e4153, 0.5);
     }
   }
-  .btn-login-oauth.fcbtn#google {
+
+  // google
+  .fcbtn#google {
     .btn-label {
-      background: rgba(#f13d25, 0.4);
+      background-color: rgba(#24292e, 0.4);
     }
-    &:after {
+
+    .eff {
       background-color: #555;
     }
   }
-  .btn-login-oauth.fcbtn#github {
+
+  // github
+  .fcbtn#github {
     .btn-label {
-      background-color: rgba(#24292e, 0.4);
+      background-color: rgba(lighten(black, 20%), 0.4);
     }
-    &:after {
+
+    .eff {
       background-color: #555;
     }
   }
-  .btn-login-oauth.fcbtn#facebook {
+
+  // facebook
+  .fcbtn#facebook {
     .btn-label {
       background-color: rgba(#29487d, 0.4);
     }
-    &:after {
+
+    .eff {
       background-color: #555;
     }
   }
-  .btn-login-oauth.fcbtn#twitter {
+
+  // twitter
+  .fcbtn#twitter {
     .btn-label {
       background-color: rgba(#1da1f2, 0.4);
     }
-    &:after {
+
+    .eff {
       background-color: #555;
     }
   }
-  .btn-login-oauth.fcbtn#saml {
+
+  // oidc
+  .fcbtn#oidc {
+    .btn-label {
+      background-color: rgba(#24292e, 0.4);
+    }
+
+    .eff {
+      background-color: #555;
+    }
+  }
+
+  // saml
+  .fcbtn#saml {
     .btn-label {
       background-color: rgba(#55a79a, 0.4);
     }
-    &:after {
+
+    .eff {
       background-color: #555;
     }
   }
-  .btn-register.fcbtn {
+
+  // basic
+  .fcbtn#basic {
     .btn-label {
-      background-color: rgba($success, 0.4);
+      background-color: rgba(#24292e, 0.4);
     }
-    .btn-label-text {
-      display: inline-block;
-      min-width: 45px;
+
+    .eff {
+      background-color: #555;
     }
-    &:after {
-      background-color: #3f7263;
+  }
+
+  // external-auth
+  .btn-collapse-external-auth {
+    color: white;
+    background-color: rgba(lighten(black, 20%), 0.4);
+    border: none;
+
+    .btn-label {
+      padding: 9px 15px;
+      margin: -8px 20px -8px -20px;
+    }
+
+    &:focus {
+      border: none;
     }
   }
 
-  hr {
-    margin: 10px 0;
-    border-color: #ccc;
+  // register
+  .fcbtn#register {
+    .btn-label {
+      background-color: rgba($success, 0.4);
+    }
+
+    .eff {
+      background-color: rgba(#3f7263, 0.5);
+    }
   }
 
   // footer link text
@@ -218,16 +300,20 @@
     &:hover,
     &.focus {
       color: black;
+
       .growi {
         color: darken($growi-green, 20%);
       }
+
       .org {
         color: darken($growi-blue, 15%);
       }
     }
   }
+
   .link-switch {
     color: $gray-200;
+
     &:hover {
       color: white;
     }
@@ -241,11 +327,13 @@
       .col-sm-offset-4 {
         margin-left: calc(50% - 160px);
       }
+
       .col-sm-4 {
         width: 320px;
       }
     }
   }
+
   .link-growi-org {
     position: absolute;
     bottom: 9px;
@@ -258,6 +346,7 @@
 
     &.to-flip {
       min-height: 295px;
+
       // has-error
       &.has-error {
         min-height: #{295px + 32px};
@@ -273,26 +362,30 @@
       -webkit-backface-visibility: hidden;
       -webkit-transform-style: preserve-3d;
     }
+
     .front {
       z-index: 2;
     }
+
     .back {
       position: absolute;
       top: 0;
       right: 15px;
       left: 15px;
     }
+
     .back,
     &.to-flip .front {
       transform: rotateY(180deg);
 
       // fix https://github.com/weseek/growi/issues/330
       // 'backface-visibility: hidden' and 'z-index: -1' breaks layout in iOS
-      .fcbtn:after {
+      ::after {
         z-index: 0;
         opacity: 0.3;
       }
     }
+
     &.to-flip .back {
       transform: rotateY(0deg);
     }
@@ -306,6 +399,7 @@
       .col-sm-offset-4 {
         margin-left: calc(50% - 240px);
       }
+
       .col-sm-4 {
         width: 480px;
       }

+ 1 - 2
src/client/styles/scss/_on-edit.scss

@@ -34,12 +34,11 @@ body.on-edit {
   .users-info,
   .user-page-content-container,
   .portal-form-button,
-  .alert-info.alert-moved,
-  .alert-info.alert-unlinked,
   .btn-like,
   .btn-bookmark,
   .btn-edit,
   .authors,
+  .hide-on-edit,
   footer {
     display: none !important;
   }

+ 0 - 8
src/client/styles/scss/_page.scss

@@ -30,14 +30,6 @@
   }
 }
 
-// alert component settings
-.alert-trash,
-.alert-moved,
-.alert-unlinked,
-.alert-grant {
-  padding: 10px 15px;
-}
-
 .main .content-main .revision-history {
   .revision-history-list {
     .revision-history-outer {

+ 322 - 280
src/server/views/login.html

@@ -25,321 +25,363 @@
 <div class="main container-fluid">
 
   <div class="row">
-    <div class="login-header col-sm-offset-4 col-sm-4">
-      <div class="logo">{% include 'widget/logo.html' %}</div>
-      <h1>{{ appService.getAppTitle() }}</h1>
-
-      <div class="login-form-errors">
-        {% if isLdapSetupFailed() %}
-        <div class="alert alert-warning small">
-          <strong><i class="icon-fw icon-info"></i>LDAP is enabled but the configuration has something wrong.</strong>
-          <br>
-          (Please set the environment variables <code>DEBUG=crowi:service:PassportService</code> to get the logs)
-        </div>
-        {% endif %}
-
-        {#
-        # The case that there already exists a user whose username matches ID of the newly created LDAP user
-        # https://github.com/weseek/growi/issues/193
-        #}
-        {% set failedProviderForDuplicatedUsernameException = req.flash('provider-DuplicatedUsernameException') %}
-        {% if failedProviderForDuplicatedUsernameException != null %}
-        <div class="alert alert-warning small">
-          <p><strong><i class="icon-fw icon-ban"></i>DuplicatedUsernameException occured</strong></p>
-          <p>
-            Your {{ failedProviderForDuplicatedUsernameException }} authentication was succeess, but a new user could not be created.
-            See the issue <a href="https://github.com/weseek/growi/issues/193">#193</a>.
-          </p>
-        </div>
-        {% endif %}
+    <div class="col-md-12">
+      <div class="login-header mx-auto">
+        <div class="logo mb-3">{% include 'widget/logo.html' %}</div>
+        <h1>{{ appService.getAppTitle() }}</h1>
+
+        <div class="login-form-errors">
+          {% if isLdapSetupFailed() %}
+          <div class="alert alert-warning small">
+            <strong><i class="icon-fw icon-info"></i>LDAP is enabled but the configuration has something wrong.</strong>
+            <br>
+            (Please set the environment variables <code>DEBUG=crowi:service:PassportService</code> to get the logs)
+          </div>
+          {% endif %}
 
-        {% set success = req.flash('successMessage') %}
-        {% if success.length %}
-        <div class="alert alert-success">
-          {{ success }}
-        </div>
-        {% endif %}
+          {#
+          # The case that there already exists a user whose username matches ID of the newly created LDAP user
+          # https://github.com/weseek/growi/issues/193
+          #}
+          {% set failedProviderForDuplicatedUsernameException = req.flash('provider-DuplicatedUsernameException') %}
+          {% if failedProviderForDuplicatedUsernameException != null %}
+          <div class="alert alert-warning small">
+            <p><strong><i class="icon-fw icon-ban"></i>DuplicatedUsernameException occured</strong></p>
+            <p>
+              Your {{ failedProviderForDuplicatedUsernameException }} authentication was succeess, but a new user could not be created.
+              See the issue <a href="https://github.com/weseek/growi/issues/193">#193</a>.
+            </p>
+          </div>
+          {% endif %}
 
-        {% set warn = req.flash('warningMessage') %}
-        {% if warn.length %}
-        {% for w in warn %}
-        <div class="alert alert-warning">
-          {{ w }}
-        </div>
-        {% endfor %}
-        {% endif %}
-
-        {% set error = req.flash('errorMessage') %}
-        {% if error.length %}
-        {% for e in error %}
-        <div class="alert alert-danger">
-          {{ e }}
-        </div>
-        {% endfor %}
-        {% endif %}
-
-        {% if req.form.errors.length > 0 %}
-        <div class="alert alert-danger">
-          <ul>
-          {% for error in req.form.errors %}
-            <li>{{ error }}</li>
+          {% set success = req.flash('successMessage') %}
+          {% if success.length %}
+          <div class="alert alert-success">
+            {{ success }}
+          </div>
+          {% endif %}
+
+          {% set warn = req.flash('warningMessage') %}
+          {% if warn.length %}
+          {% for w in warn %}
+          <div class="alert alert-warning">
+            {{ w }}
+          </div>
           {% endfor %}
-          </ul>
+          {% endif %}
+
+          {% set error = req.flash('errorMessage') %}
+          {% if error.length %}
+          {% for e in error %}
+          <div class="alert alert-danger">
+            {{ e }}
+          </div>
+          {% endfor %}
+          {% endif %}
+
+          {% if req.form.errors.length > 0 %}
+          <div class="alert alert-danger">
+            <ul>
+            {% for error in req.form.errors %}
+              <li>{{ error }}</li>
+            {% endfor %}
+            </ul>
+          </div>
+          {% endif %}
         </div>
-        {% endif %}
-      </div>
-      <div id="register-form-errors">
-        {% set message = req.flash('registerWarningMessage') %}
-        {% if message.length %}
-        <div class="alert alert-danger">
-          {% for msg in message %}
-          {{ msg }}<br>
-          {% endfor  %}
+        <div id="register-form-errors">
+          {% set message = req.flash('registerWarningMessage') %}
+          {% if message.length %}
+          <div class="alert alert-danger">
+            {% for msg in message %}
+            {{ msg }}<br>
+            {% endfor  %}
+          </div>
+          {% endif %}
         </div>
-        {% endif %}
       </div>
     </div>
+  </div>
 
+  <div class="row mb-5">
+    <div class="col-md-12">
 
     {% set isLocalOrLdapStrategiesEnabled = passportService.isLocalStrategySetup || passportService.isLdapStrategySetup %}
     {% set isExternalAuthCollapsible = isLocalOrLdapStrategiesEnabled %}
     {% set isRegistrationEnabled = passportService.isLocalStrategySetup && getConfig('crowi', 'security:registrationMode') != 'Closed' %}
 
-    <div class="login-dialog p-b-10 col-sm-offset-4 col-sm-4 flipper {% if req.query.register or req.body.registerForm or isRegistering %}to-flip{% endif %}" id="login-dialog">
-
-      <div class="front">
-
-        {% if isLocalOrLdapStrategiesEnabled %}
-        <form role="form" action="/login" method="post">
-          <div class="input-group">
-            <span class="input-group-addon"><i class="icon-user"></i></span>
-            <input type="text" class="form-control" placeholder="Username or E-mail" name="loginForm[username]">
-            {% if passportService.isLdapStrategySetup %}
-            <span class="input-group-addon">
-              <small class="text-success">
-                <i class="icon-fw icon-check"></i> LDAP
-              </small>
-            </span>
-            {% endif %}
-          </div>
-
-          <div class="input-group">
-            <span class="input-group-addon"><i class="icon-lock"></i></span>
-            <input type="password" class="form-control" placeholder="Password" name="loginForm[password]">
-          </div>
+      <div class="login-dialog mx-auto flipper {% if req.query.register or req.body.registerForm or isRegistering %}to-flip{% endif %}" id="login-dialog">
+
+        <div class="col-12">
+          <div class="front">
+
+            {% if isLocalOrLdapStrategiesEnabled %}
+            <form role="form" action="/login" method="post">
+
+              <div class="input-group">
+                <div class="input-group-prepend">
+                  <span class="input-group-text"><i class="icon-user"></i></span>
+                </div>
+                <input type="text" class="form-control" placeholder="Username or E-mail" name="loginForm[username]">
+                {% if passportService.isLdapStrategySetup %}
+                <span class="input-group-append">
+                  <small class="text-success">
+                    <i class="icon-fw icon-check"></i> LDAP
+                  </small>
+                </span>
+                {% endif %}
+              </div>
+
+              <div class="input-group">
+                <div class="input-group-prepend">
+                  <span class="input-group-text"><i class="icon-lock"></i></span>
+                </div>
+                <input type="password" class="form-control" placeholder="Password" name="loginForm[password]">
+              </div>
+
+              <div class="input-group justify-content-center d-flex mt-5">
+                <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                <button type="submit" class="btn fcbtn login px-0 py-2">
+                  <div class="eff"></div>
+                  <span class="btn-label p-3"><i class="icon-login"></i></span>
+                  <span class="btn-label-text p-3">{{ t('Sign in') }}</span>
+                </button>
+              </div>
 
-          <div class="input-group mt-5 m-b-20 d-flex justify-content-center">
-            <input type="hidden" name="_csrf" value="{{ csrf() }}">
-            <button type="submit" class="fcbtn btn btn-danger btn-1b btn-login">
-              <span class="btn-label"><i class="icon-login"></i></span>
-              {{ t('Sign in') }}
-            </button>
-          </div>
-        </form>
-        {% endif %}
-
-        {% if (
-          getConfig('crowi', 'security:passport-google:isEnabled') ||
-          getConfig('crowi', 'security:passport-github:isEnabled') ||
-          getConfig('crowi', 'security:passport-facebook:isEnabled') ||
-          getConfig('crowi', 'security:passport-twitter:isEnabled')||
-          getConfig('crowi', 'security:passport-oidc:isEnabled') ||
-          getConfig('crowi', 'security:passport-saml:isEnabled') ||
-          getConfig('crowi', 'security:passport-basic:isEnabled')
-        ) %}
-        <hr class="mb-1">
-        <div id="external-auth" class="external-auth {% if isExternalAuthCollapsible %}collapse collapse-external-auth collapse-anchor{% endif %}">
-          <div class="spacer"></div>
-          <div class="d-flex flex-row justify-content-between flex-wrap">
-            {% if getConfig('crowi', 'security:passport-google:isEnabled') %}
-            <form role="form" action="/passport/google" class="d-inline-flex flex-column">
-              <button type="submit" class="fcbtn btn btn-1b btn-login-oauth d-flex" id="google">
-                <span class="btn-label"><i class="fa fa-google"></i></span>
-                <span class="btn-label-text">{{ t('Sign in') }}</span>
-              </button>
-              <div class="small text-right">by Google Account</div>
             </form>
             {% endif %}
-            {% if getConfig('crowi', 'security:passport-github:isEnabled') %}
-            <form role="form" action="/passport/github" class="d-inline-flex flex-column">
-              <input type="hidden" name="_csrf" value="{{ csrf() }}">
-              <button type="submit" class="fcbtn btn btn-1b btn-login-oauth d-inline-flex" id="github">
-                <span class="btn-label"><i class="fa fa-github"></i></span>
-                <span class="btn-label-text">{{ t('Sign in') }}</span>
-              </button>
-              <div class="small text-right">by GitHub Account</div>
-            </form>
-            {% endif %}
-            {% if getConfig('crowi', 'security:passport-facebook:isEnabled') %}
-            <form role="form" action="/passport/facebook" class="d-inline-flex flex-column">
-              <input type="hidden" name="_csrf" value="{{ csrf() }}">
-              <button type="submit" class="fcbtn btn btn-1b btn-login-oauth d-inline-flex" id="facebook">
-                <span class="btn-label"><i class="fa fa-facebook"></i></span>
-                <span class="btn-label-text">{{ t('Sign in') }}</span>
-              </button>
-              <div class="small text-right">by Facebook Account</div>
-            </form>
-            {% endif %}
-            {% if getConfig('crowi', 'security:passport-twitter:isEnabled') %}
-            <form role="form" action="/passport/twitter" class="d-inline-flex flex-column">
-              <input type="hidden" name="_csrf" value="{{ csrf() }}">
-              <button type="submit" class="fcbtn btn btn-1b btn-login-oauth d-inline-flex" id="twitter">
-                <span class="btn-label"><i class="fa fa-twitter"></i></span>
-                <span class="btn-label-text">{{ t('Sign in') }}</span>
-              </button>
-              <div class="small text-right">by Twitter Account</div>
-            </form>
-            {% endif %}
-            {% if getConfig('crowi', 'security:passport-oidc:isEnabled') %}
-            <form role="form" action="/passport/oidc" class="d-inline-flex flex-column">
-              <input type="hidden" name="_csrf" value="{{ csrf() }}">
-              <button type="submit" class="fcbtn btn btn-1b btn-login-oauth d-inline-flex" id="oidc">
-                <span class="btn-label"><i class="fa fa-openid"></i></span>
-                <span class="btn-label-text">{{ t('Sign in') }}</span>
-              </button>
-              <div class="small text-right">{{ getConfig('crowi', 'security:passport-oidc:providerName') || "OpenID Connect" }}</div>
-            </form>
-            {% endif %}
-            {% if getConfig('crowi', 'security:passport-saml:isEnabled') %}
-            <form role="form" action="/passport/saml" class="d-inline-flex flex-column">
-              <input type="hidden" name="_csrf" value="{{ csrf() }}">
-              <button type="submit" class="fcbtn btn btn-1b btn-login-oauth d-inline-flex" id="saml">
-                <span class="btn-label"><i class="fa fa-key"></i></span>
-                <span class="btn-label-text">{{ t('Sign in') }}</span>
-              </button>
-              <div class="small text-right">with SAML</div>
-            </form>
-            {% endif %}
-            {% if getConfig('crowi', 'security:passport-basic:isEnabled') %}
-            <form role="form" action="/passport/basic" class="d-inline-flex flex-column">
-              <input type="hidden" name="_csrf" value="{{ csrf() }}">
-              <button type="submit" class="fcbtn btn btn-1b btn-login-oauth d-inline-flex" id="basic">
-                <span class="btn-label"><i class="fa fa-lock"></i></span>
-                <span class="btn-label-text">{{ t('Sign in') }}</span>
+
+            {% if (
+              getConfig('crowi', 'security:passport-google:isEnabled') ||
+              getConfig('crowi', 'security:passport-github:isEnabled') ||
+              getConfig('crowi', 'security:passport-facebook:isEnabled') ||
+              getConfig('crowi', 'security:passport-twitter:isEnabled')||
+              getConfig('crowi', 'security:passport-oidc:isEnabled') ||
+              getConfig('crowi', 'security:passport-saml:isEnabled') ||
+              getConfig('crowi', 'security:passport-basic:isEnabled')
+            ) %}
+            <div class="border-bottom"></div>
+            <div id="external-auth" class="external-auth {% if isExternalAuthCollapsible %}collapse collapse-external-auth collapse-anchor{% endif %}">
+              <div class="spacer"></div>
+              <div class="d-flex flex-row justify-content-between flex-wrap">
+                {% if getConfig('crowi', 'security:passport-google:isEnabled') %}
+                <div class="input-group justify-content-center d-flex mt-5">
+                  <form role="form" action="/passport/google" class="d-inline-flex flex-column">
+                    <button type="submit" class="btn fcbtn px-0 py-2" id="google">
+                      <div class="eff"></div>
+                      <span class="btn-label p-3"><i class="fa fa-google"></i></span>
+                      <span class="btn-label-text p-3">{{ t('Sign in') }}</span>
+                    </button>
+                    <div class="small text-center">by Google Account</div>
+                  </form>
+                </div>
+                {% endif %}
+                {% if getConfig('crowi', 'security:passport-github:isEnabled') %}
+                <div class="input-group justify-content-center d-flex mt-5">
+                  <form role="form" action="/passport/github" class="d-inline-flex flex-column">
+                    <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                    <button type="submit" class="btn fcbtn px-0 py-2" id="github">
+                      <div class="eff"></div>
+                      <span class="btn-label p-3"><i class="fa fa-github"></i></span>
+                      <span class="btn-label-text p-3">{{ t('Sign in') }}</span>
+                    </button>
+                    <div class="small text-center">by GitHub Account</div>
+                  </form>
+                </div>
+                {% endif %}
+                {% if getConfig('crowi', 'security:passport-facebook:isEnabled') %}
+                <div class="input-group justify-content-center d-flex mt-5">
+                  <form role="form" action="/passport/facebook" class="d-inline-flex flex-column">
+                    <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                    <button type="submit" class="btn fcbtn px-0 py-2" id="facebook">
+                      <div class="eff"></div>
+                      <span class="btn-label p-3"><i class="fa fa-facebook"></i></span>
+                      <span class="btn-label-text p-3">{{ t('Sign in') }}</span>
+                    </button>
+                    <div class="small text-center">by Facebook Account</div>
+                  </form>
+                </div>
+                {% endif %}
+                {% if getConfig('crowi', 'security:passport-twitter:isEnabled') %}
+                <div class="input-group justify-content-center d-flex mt-5">
+                  <form role="form" action="/passport/twitter" class="d-inline-flex flex-column">
+                    <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                    <button type="submit" class="btn fcbtn px-0 py-2" id="twitter">
+                      <div class="eff"></div>
+                      <span class="btn-label p-3"><i class="fa fa-twitter"></i></span>
+                      <span class="btn-label-text p-3">{{ t('Sign in') }}</span>
+                    </button>
+                    <div class="small text-center">by Twitter Account</div>
+                  </form>
+                </div>
+                {% endif %}
+                {% if getConfig('crowi', 'security:passport-oidc:isEnabled') %}
+                <div class="input-group justify-content-center d-flex mt-5">
+                  <form role="form" action="/passport/oidc" class="d-inline-flex flex-column">
+                    <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                    <button type="submit" class="btn fcbtn px-0 py-2" id="oidc">
+                      <div class="eff"></div>
+                      <span class="btn-label p-3"><i class="fa fa-openid"></i></span>
+                      <span class="btn-label-text p-3">{{ t('Sign in') }}</span>
+                    </button>
+                    <div class="small text-center">{{ getConfig('crowi', 'security:passport-oidc:providerName') || "OpenID Connect" }}</div>
+                  </form>
+                </div>
+                {% endif %}
+                {% if getConfig('crowi', 'security:passport-saml:isEnabled') %}
+                <div class="input-group justify-content-center d-flex mt-5">
+                  <form role="form" action="/passport/saml" class="d-inline-flex flex-column">
+                    <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                    <button type="submit" class="btn fcbtn px-0 py-2" id="saml">
+                      <div class="eff"></div>
+                      <span class="btn-label p-3"><i class="fa fa-key"></i></span>
+                      <span class="btn-label-text p-3">{{ t('Sign in') }}</span>
+                    </button>
+                    <div class="small text-center">with SAML</div>
+                  </form>
+                </div>
+                {% endif %}
+                {% if getConfig('crowi', 'security:passport-basic:isEnabled') %}
+                <div class="input-group justify-content-center d-flex mt-5">
+                  <form role="form" action="/passport/basic" class="d-inline-flex flex-column">
+                    <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                    <button type="submit" class="btn fcbtn px-0 py-2" id="basic">
+                      <div class="eff"></div>
+                      <span class="btn-label p-3"><i class="fa fa-lock"></i></span>
+                      <span class="btn-label-text p-3">{{ t('Sign in') }}</span>
+                    </button>
+                    <div class="small text-center">with Basic Auth</div>
+                  </form>
+                </div>
+              {% endif %}
+              </div>{# ./d-flex flex-row flex-wrap #}
+              <div class="spacer"></div>
+            </div>
+            <div class="border-bottom"></div>
+            <div class="text-center">
+              <button class="collapse-anchor btn btn-xs btn-collapse-external-auth mb-3"
+                  data-toggle="{% if isExternalAuthCollapsible %}collapse{% endif %}" data-target="#external-auth" aria-expanded="false" aria-controls="external-auth">
+                External Auth
               </button>
-              <div class="small text-right">with Basic Auth</div>
-            </form>
-            {% endif %}
-          </div>{# ./d-flex flex-row flex-wrap #}
-          <div class="spacer"></div>
-        </div>
-        <hr class="mt-2 mb-0">
-        <div class="text-center">
-          <button class="collapse-anchor btn btn-xs btn-collapse-external-auth mb-3"
-              data-toggle="{% if isExternalAuthCollapsible %}collapse{% endif %}" data-target="#external-auth" aria-expanded="false" aria-controls="external-auth">
-            External Auth
-          </button>
-        </div>
-        {% else %}
-        <hr>
-        {% endif %}
-
-        {% if isExternalAuthCollapsible %}
-        <script>
-          const isMobile = /iphone|ipad|android/.test(window.navigator.userAgent.toLowerCase());
-
-          if (!isMobile) {
-            $(".collapse-anchor").hover(
-              function() {
-                $('.collapse-external-auth').collapse('show');
-              },
-              function() {
-                $('.collapse-external-auth').collapse('hide');
-              }
-            );
-          }
-        </script>
-        {% endif %}
-
-        <div class="row">
-          <div class="col-xs-12 text-right">
-            {% if isRegistrationEnabled %}
-            <a href="#register" id="register" class="link-switch">
-              <i class="ti-check-box"></i> {{ t('Sign up is here') }}
-            </a>
+            </div>
             {% else %}
-            &nbsp;
+            <div class="border-bottom mb-3"></div>
             {% endif %}
-          </div>
-        </div>
-
-      </div>
 
+            {% if isExternalAuthCollapsible %}
+            <script>
+              const isMobile = /iphone|ipad|android/.test(window.navigator.userAgent.toLowerCase());
+
+              if (!isMobile) {
+                $(".collapse-anchor").hover(
+                  function() {
+                    $('.collapse-external-auth').collapse('show');
+                  },
+                  function() {
+                    $('.collapse-external-auth').collapse('hide');
+                  }
+                );
+              }
+            </script>
+            {% endif %}
 
-      {% if isRegistrationEnabled %}
-      <div class="back">
-        {% if getConfig('crowi', 'security:registrationMode') == 'Restricted' %}
-        <p class="alert alert-warning">
-          {{ t('page_register.notice.restricted') }}<br>
-          {{ t('page_register.notice.restricted_defail') }}
-        </p>
-        {% endif %}
+            <div class="row">
+              <div class="col-12 text-right py-2">
+                {% if isRegistrationEnabled %}
+                <a href="#register" id="register" class="link-switch">
+                  <i class="ti-check-box"></i> {{ t('Sign up is here') }}
+                </a>
+                {% else %}
+                &nbsp;
+                {% endif %}
+              </div>
+            </div>
 
-        <form role="form" method="post" action="/register" 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="{{ req.body.registerForm.name }}" required>
-          </div>
+          {% if isRegistrationEnabled %}
+          <div class="back">
+            {% if getConfig('crowi', 'security:registrationMode') == 'Restricted' %}
+            <p class="alert alert-warning">
+              {{ t('page_register.notice.restricted') }}<br>
+              {{ t('page_register.notice.restricted_defail') }}
+            </p>
+            {% endif %}
 
-          <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="{{ req.body.registerForm.email }}" required>
-          </div>
-          {% if getConfig('crowi', 'security:registrationWhiteList') && getConfig('crowi', 'security:registrationWhiteList').length %}
-          <p class="help-block">
-            {{ t('page_register.form_help.email') }}
-          </p>
-          <ul>
-            {% for em in getConfig('crowi', 'security:registrationWhiteList') %}
-            <li><code>{{ em }}</code></li>
-            {% endfor %}
-          </ul>
-          {% endif %}
+            <form role="form" action="/register" method="post" id="register-form">
+              <div class="input-group" id="input-group-username">
+                <div class="input-group-prepend">
+                  <span class="input-group-text"><i class="icon-user"></i></span>
+                </div>
+                <input type="text" class="form-control" placeholder="{{ t('User ID') }}" name="registerForm[username]" value="{{ req.body.registerForm.username }}" required>
+              </div>
+              <p class="form-text text-danger">
+                <span id="help-block-username"></span>
+              </p>
+
+              <div class="input-group">
+                <div class="input-group-prepend">
+                  <span class="input-group-text"><i class="icon-tag"></i></span>
+                </div>
+                <input type="text" class="form-control" placeholder="{{ t('Name') }}" name="registerForm[name]" value="{{ req.body.registerForm.name }}" required>
+              </div>
+
+              <div class="input-group">
+                <div class="input-group-prepend">
+                  <span class="input-group-text"><i class="icon-envelope"></i></span>
+                </div>
+                <input type="email" class="form-control" placeholder="{{ t('Email') }}" name="registerForm[email]" value="{{ req.body.registerForm.email }}" required>
+              </div>
+              {% if getConfig('crowi', 'security:registrationWhiteList') && getConfig('crowi', 'security:registrationWhiteList').length %}
+              <p class="form-text">
+                {{ t('page_register.form_help.email') }}
+              </p>
+              <ul>
+                {% for em in getConfig('crowi', 'security:registrationWhiteList') %}
+                <li><code>{{ em }}</code></li>
+                {% endfor %}
+              </ul>
+              {% endif %}
+
+              <div class="input-group">
+                <div class="input-group-prepend">
+                  <span class="input-group-text"><i class="icon-lock"></i></span>
+                </div>
+                <input type="password" class="form-control" placeholder="{{ t('Password') }}" name="registerForm[password]" required>
+              </div>
+
+              <div class="input-group justify-content-center mt-5">
+                <input type="hidden" name="_csrf" value="{{ csrf() }}">
+                <button type="submit" class="btn fcbtn px-0 py-2" id="register">
+                  <div class="eff"></div>
+                  <span class="btn-label p-3"><i class="icon-user-follow"></i></span>
+                  <span class="btn-label-text p-3">{{ t('Sign up') }}</span>
+                </button>
+              </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>
+            </form>
 
-          <input type="hidden" name="_csrf" value="{{ csrf() }}">
+            <div class="border-bottom mb-3"></div>
 
-          <div class="input-group mt-5 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>
-              <span class="btn-label-text">{{ t('Sign up') }}</span>
-            </button>
+            <div class="row">
+              <div class="text-right col-12 py-1">
+                <a href="#login" id="login" class="link-switch">
+                  <i class="icon-fw icon-login"></i>{{ t('Sign in is here') }}
+                </a>
+              </div>
+            </div>
           </div>
-        </form>
-
-        <hr>
 
-        <div class="row">
-          <div class="col-xs-12 text-right">
-            <a href="#login" id="login" class="link-switch">
-              <i class="icon-fw icon-login"></i>{{ t('Sign in is here') }}
-            </a>
-          </div>
+          {% endif %} {# if isRegistrationEnabled id false #}
         </div>
 
-      </div>
-      {% endif %} {# if isRegistrationEnabled id false #}
-
-      <a href="https://growi.org" class="link-growi-org">
-        <span class="growi">GROWI</span>.<span class="org">ORG
-      </a>
+        <a href="https://growi.org" class="link-growi-org pl-3">
+          <span class="growi">GROWI</span>.<span class="org">ORG
+        </a>
 
+      </div>
     </div>
-
   </div>
-
 </div>
 
 {% endblock %}

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

@@ -14,7 +14,7 @@
 
   <div class="row row-alerts">
     <div class="col-xs-12">
-        <p class="alert alert-inverse alert-grant">
+        <p class="alert alert-inverse alert-grant"> <!-- TODO remove inverse and grant -->
           <i class="icon-fw icon-lock" aria-hidden="true"></i> Browsing of this page is restricted
         </p>
     </div>

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

@@ -2,7 +2,7 @@
   <div class="col-sm-12">
     {% if page && page.grant && page.grant > 1 %}
 
-      <p class="alert alert-inverse alert-grant">
+      <p class="alert alert-primary py-3 px-4">
       {% if page.grant == 2 %}
         <i class="icon-fw icon-link"></i><strong>{{ consts.pageGrants[page.grant] }}</strong> ({{ t('Browsing of this page is restricted') }})
       {% elseif page.grant == 4 %}
@@ -29,7 +29,7 @@
     {% endif %}
 
     {% if redirectFrom or req.query.renamed or req.query.redirectFrom %}
-    <div class="alert alert-info alert-moved d-flex align-items-center justify-content-between">
+    <div class="alert alert-info hide-on-edit py-3 px-4 d-flex align-items-center justify-content-between">
       <span>
         {% set fromPath = req.query.renamed or req.query.redirectFrom %}
         {% if redirectFrom or req.query.redirectFrom %}
@@ -43,7 +43,7 @@
       <form role="form" id="unlink-page-form" onsubmit="return false;">
         <input type="hidden" name="_csrf" value="{{ csrf() }}">
         <input type="hidden" name="path" value="{{ path }}">
-        <button type="submit" class="btn btn-default btn-sm float-right">
+        <button type="submit" class="btn btn-light btn-sm float-right">
           <i class="ti-unlink" aria-hidden="true"></i>
           Unlink
         </button>
@@ -53,7 +53,7 @@
     {% endif %}
 
     {% if req.query.duplicated and not page.isDeleted() %}
-    <div class="alert alert-success alert-moved">
+    <div class="alert alert-success py-3 px-4">
       <span>
         <strong>{{ t('Duplicated') }}: </strong> {{ t('page_page.notice.duplicated', req.sanitize(req.query.duplicated)) }}
       </span>
@@ -61,7 +61,7 @@
     {% endif %}
 
     {% if req.query.unlinked %}
-    <div class="alert alert-info alert-unlinked">
+    <div class="alert alert-info hide-on-edit py-3 px-4">
       <strong>{{ t('Unlinked') }}: </strong> {{ t('page_page.notice.unlinked') }}
     </div>
     {% endif %}
@@ -81,7 +81,7 @@
     {% endif %}
 
     {% if isTrashPage() %}
-    <div class="alert alert-warning alert-trash d-flex align-items-center justify-content-between">
+    <div class="alert alert-warning py-3 px-4 d-flex align-items-center justify-content-between">
       <div>
         This page is in the trash <i class="icon-trash" aria-hidden="true"></i>.
         {% if page.isDeleted() %}