Browse Source

Merge pull request #53 from crowi/portal-transport

Portal transport, improve ux
Sotaro KARASAWA 10 years ago
parent
commit
64945a7762

+ 10 - 3
lib/routes/page.js

@@ -200,8 +200,15 @@ module.exports = function(crowi, app) {
         return res.redirect('/');
         return res.redirect('/');
       }
       }
 
 
-      debug('Catch pageShow', err);
-      return renderPage(null, req, res);
+      Page.hasPortalPage(path + '/', req.user)
+      .then(function(page) {
+        if (page) {
+          return res.redirect(path + '/');
+        } else {
+          debug('Catch pageShow', err);
+          return renderPage(null, req, res);
+        }
+      });
     });
     });
   };
   };
 
 
@@ -377,7 +384,7 @@ module.exports = function(crowi, app) {
       var result = {};
       var result = {};
       result.page = pageData;
       result.page = pageData;
 
 
-      return res.json(ApiResponse.success(pageData));
+      return res.json(ApiResponse.success(result));
     }).catch(function(err) {
     }).catch(function(err) {
       return res.json(ApiResponse.error(err));
       return res.json(ApiResponse.error(err));
     });
     });

+ 16 - 0
lib/util/middlewares.js

@@ -59,6 +59,22 @@ exports.swigFilters = function(app, swig) {
         .replace(/\n/g, '<br>');
         .replace(/\n/g, '<br>');
     });
     });
 
 
+    swig.setFilter('insertSpaceToEachSlashes', function(string) {
+      if (string == '/') {
+        return string;
+      }
+
+      return string.replace(/\//g, ' / ');
+    });
+
+    swig.setFilter('removeLastSlash', function(string) {
+      if (string == '/') {
+        return string;
+      }
+
+      return string.substr(0, string.length - 1);
+    });
+
     swig.setFilter('presentation', function(string) {
     swig.setFilter('presentation', function(string) {
       // 手抜き
       // 手抜き
       return string
       return string

+ 8 - 0
lib/util/swigFunctions.js

@@ -20,6 +20,14 @@ module.exports = function(crowi, app, locals) {
     return Config.isUploadable(config);
     return Config.isUploadable(config);
   };
   };
 
 
+  locals.isUserPageList = function(path) {
+    if (path.match(/^\/user\/[^\/]+\/$/)) {
+      return true;
+    }
+
+    return false;
+  };
+
   locals.user_page_root = function(user) {
   locals.user_page_root = function(user) {
     if (!user) {
     if (!user) {
       return '';
       return '';

+ 10 - 1
lib/views/page.html

@@ -15,7 +15,7 @@
     {% if page %}
     {% if page %}
       <a href="#" title="Bookmark" class="bookmark-link" id="bookmark-button" data-bookmarked="0"><i class="fa fa-star-o"></i></a>
       <a href="#" title="Bookmark" class="bookmark-link" id="bookmark-button" data-bookmarked="0"><i class="fa fa-star-o"></i></a>
     {% endif %}
     {% endif %}
-    <h1 class="title" id="revision-path">{{ path }}</h1>
+    <h1 class="title" id="revision-path">{{ path|insertSpaceToEachSlashes }}</h1>
   </header>
   </header>
 </div>
 </div>
 
 
@@ -30,6 +30,8 @@
 {% endblock %}
 {% endblock %}
 
 
 <div id="content-main" class="content-main {% if not page or req.body.pageForm %}on-edit{% endif %}"
 <div id="content-main" class="content-main {% if not page or req.body.pageForm %}on-edit{% endif %}"
+  data-path="{{ path }}"
+  data-path-shortname="{{ path|path2name }}"
   data-page-id="{% if page %}{{ page._id.toString() }}{% endif %}"
   data-page-id="{% if page %}{{ page._id.toString() }}{% endif %}"
   data-current-user="{% if user %}{{ user._id.toString() }}{% endif %}"
   data-current-user="{% if user %}{{ user._id.toString() }}{% endif %}"
   data-page-revision-id="{% if revision %}{{ revision._id.toString() }}{% endif %}"
   data-page-revision-id="{% if revision %}{{ revision._id.toString() }}{% endif %}"
@@ -216,6 +218,13 @@
 <div id="notifPageEdited" class="fk-hide fk-notif fk-notif-danger"><i class="fa fa-exclamation-triangle"></i> <span class="edited-user"></span>さんがこのページを編集しました。 <a href="javascript:location.reload();"><i class="fa fa-angle-double-right"></i> 最新版を読み込む</a></div>
 <div id="notifPageEdited" class="fk-hide fk-notif fk-notif-danger"><i class="fa fa-exclamation-triangle"></i> <span class="edited-user"></span>さんがこのページを編集しました。 <a href="javascript:location.reload();"><i class="fa fa-angle-double-right"></i> 最新版を読み込む</a></div>
 <div id="notifPageEditing" class="fk-hide fk-notif fk-notif-warning"><i class="fa fa-exclamation-triangle"></i> 他の人がこのページの編集を開始しました。</div>
 <div id="notifPageEditing" class="fk-hide fk-notif fk-notif-warning"><i class="fa fa-exclamation-triangle"></i> 他の人がこのページの編集を開始しました。</div>
 
 
+<div id="portal-warning-for-page" class="portal-warning-for-page alert alert-danger alert-dismissible" role="alert">
+  <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+
+  <strong>Warning!</strong> /user/hoge のページが存在します。このページをポータル化するには、/ に移動し、「ページを移動」させてください。<br>
+/ とは別に ポータル を作成する場合、このまま編集を続けて作成してください。
+</div>
+
 <script>
 <script>
   $(function() {
   $(function() {
     var me = {{ user|json|safe }};
     var me = {{ user|json|safe }};

+ 32 - 4
lib/views/page_list.html

@@ -14,7 +14,7 @@
 
 
     {% endif %}
     {% endif %}
     <h1 class="title" id="revision-path">
     <h1 class="title" id="revision-path">
-      {{ path }}
+      {{ path|insertSpaceToEachSlashes }}
     </h1>
     </h1>
   </header>
   </header>
 </div>
 </div>
@@ -31,6 +31,8 @@
 
 
 <div class="page-list content-main {% if req.body.pageForm %}on-edit{% endif %}"
 <div class="page-list content-main {% if req.body.pageForm %}on-edit{% endif %}"
   id="content-main"
   id="content-main"
+  data-path="{{ path }}"
+  data-path-shortname="{{ path|path2name }}"
   data-page-portal="{% if page and page.isPortal() %}1{% else %}0{% endif %}"
   data-page-portal="{% if page and page.isPortal() %}1{% else %}0{% endif %}"
   data-page-id="{% if page %}{{ page._id.toString() }}{% endif %}"
   data-page-id="{% if page %}{{ page._id.toString() }}{% endif %}"
   data-current-user="{% if user %}{{ user._id.toString() }}{% endif %}"
   data-current-user="{% if user %}{{ user._id.toString() }}{% endif %}"
@@ -65,8 +67,7 @@
   </ul>
   </ul>
 
 
   <div class="tab-content">
   <div class="tab-content">
-    <div class="wiki tab-pane {% if not req.body.pageForm %}active{% endif %}" id="revision-body-content">
-    </div>
+    <div class="wiki tab-pane {% if not req.body.pageForm %}active{% endif %}" id="revision-body-content">{{ page.revision.body|nl2br|safe }}</div>
 
 
     <script type="text/template" id="raw-text-original">{{ page.revision.body }}</script>
     <script type="text/template" id="raw-text-original">{{ page.revision.body }}</script>
     <script type="text/javascript">
     <script type="text/javascript">
@@ -160,7 +161,7 @@
 
 
 {% block side_header %}
 {% block side_header %}
 
 
-{% if not page %}
+{% if not page and not isUserPageList(path) %}
 <div class="portal-side">
 <div class="portal-side">
   <div class="portal-form-button">
   <div class="portal-form-button">
     <button class="btn btn-primary" id="create-portal-button">Create Portal</button>
     <button class="btn btn-primary" id="create-portal-button">Create Portal</button>
@@ -174,3 +175,30 @@
 
 
 {% endblock %} {# side_header #}
 {% endblock %} {# side_header #}
 
 
+{% block body_end %}
+<div class="modal fade portal-warning-modal" id="portal-warning-modal">
+  <div class="modal-dialog">
+    <div class="modal-content">
+
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <h4 class="modal-title">ポータルに関するヒント</h4>
+      </div>
+      <div class="modal-body alert alert-danger">
+
+        <strong>Warning!</strong><br>
+
+        <p>既に <strong><a href="{{ path|removeLastSlash }}">{{ path|removeLastSlash }}</a></strong> のページが存在します。</p>
+
+        <p>
+          <a href="{{ path|removeLastSlash }}">{{ path|removeLastSlash }}</a> をポータル化するには、
+          <a href="{{ path|removeLastSlash }}">{{ path|removeLastSlash }}</a> に移動し、「ページを移動」させてください。<br>
+          <a href="{{ path|removeLastSlash }}">{{ path|removeLastSlash }}</a> とは別に、このページ(<code>{{ path }}</code>)にポータルを作成する場合、このまま編集を続けて作成してください。
+        </p>
+
+      </div>
+    </div>
+  </div>
+</div>
+</div>
+{% endblock %} {# body_end #}

+ 1 - 1
lib/views/user_page.html

@@ -7,7 +7,7 @@
 {% if pageUser %}
 {% if pageUser %}
 
 
 <div class="header-wrap">
 <div class="header-wrap">
-  <h1 class="title" id="revision-path">{{ path }}</h1>
+  <h1 class="title" id="revision-path">{{ path|insertSpaceToEachSlashes }}</h1>
   <div class="user-page-header">
   <div class="user-page-header">
   {% if page %}
   {% if page %}
     <a href="#" title="Bookmark" class="bookmark-link" id="bookmark-button" data-bookmarked="0"><i class="fa fa-star-o"></i></a>
     <a href="#" title="Bookmark" class="bookmark-link" id="bookmark-button" data-bookmarked="0"><i class="fa fa-star-o"></i></a>

+ 1 - 0
resource/css/_page.scss

@@ -63,6 +63,7 @@
       }
       }
 
 
       h1 {
       h1 {
+        font-size: 28px;
         margin-top: 0;
         margin-top: 0;
 
 
         a:last-child {
         a:last-child {

+ 5 - 0
resource/css/_portal.scss

@@ -29,3 +29,8 @@
     text-align: center;
     text-align: center;
   }
   }
 } // .portal-side
 } // .portal-side
+
+
+.portal-warning-modal {
+  z-index: 1062;
+}

+ 13 - 5
resource/js/crowi.js

@@ -19,10 +19,8 @@ Crowi.createErrorView = function(msg) {
 Crowi.linkPath = function(revisionPath) {
 Crowi.linkPath = function(revisionPath) {
   var $revisionPath = revisionPath || '#revision-path';
   var $revisionPath = revisionPath || '#revision-path';
   var $title = $($revisionPath);
   var $title = $($revisionPath);
-  if (!$title.get(0)) {
-    return;
-  }
-  var realPath = $title.text().trim();
+
+  var realPath = $('#content-main').data('path').trim();
   if (realPath.substr(-1, 1) == '/') {
   if (realPath.substr(-1, 1) == '/') {
     realPath = realPath.substr(0, realPath.length - 1);
     realPath = realPath.substr(0, realPath.length - 1);
   }
   }
@@ -287,6 +285,16 @@ $(function() {
     $('.portal').removeClass('hide');
     $('.portal').removeClass('hide');
     $('.content-main').addClass('on-edit');
     $('.content-main').addClass('on-edit');
     $('.portal a[data-toggle="tab"][href="#edit-form"]').tab('show');
     $('.portal a[data-toggle="tab"][href="#edit-form"]').tab('show');
+
+    var path = $('.content-main').data('path');
+    if (path != '/' && $('.content-main').data('page-id') == '') {
+      var upperPage = path.substr(0, path.length - 1);
+      $.get('/_api/pages.get', {path: upperPage}, function(res) {
+        if (res.ok && res.page) {
+          $('#portal-warning-modal').modal('show');
+        }
+      });
+    }
   });
   });
   $('#portal-form-close').on('click', function(e) {
   $('#portal-form-close').on('click', function(e) {
     $('.portal').addClass('hide');
     $('.portal').addClass('hide');
@@ -537,7 +545,7 @@ $(function() {
 
 
     var $seenUserList = $("#seen-user-list");
     var $seenUserList = $("#seen-user-list");
     var seenUsers = $seenUserList.data('seen-users');
     var seenUsers = $seenUserList.data('seen-users');
-    if (seenUsers && seenUsers.length > 0) {
+    if (seenUsers && seenUsers.length > 0 && seenUsers.length <= 10) {
       // FIXME: user data cache
       // FIXME: user data cache
       $.get('/_api/users.list', {user_ids: seenUsers}, function(res) {
       $.get('/_api/users.list', {user_ids: seenUsers}, function(res) {
         // ignore unless response has error
         // ignore unless response has error