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

Merge pull request #101 from weseek/feat/integrated-blank-page

Feat/integrated blank page
Yuki Takei 8 лет назад
Родитель
Сommit
68c63618a8

+ 9 - 0
lib/form/admin/custombehavior.js

@@ -0,0 +1,9 @@
+'use strict';
+
+var form = require('express-form')
+  , field = form.field
+  ;
+
+module.exports = form(
+  field('settingForm[customize:behavior]')
+);

+ 1 - 0
lib/form/index.js

@@ -19,6 +19,7 @@ module.exports = {
     plugin: require('./admin/plugin'),
     markdown: require('./admin/markdown'),
     customcss: require('./admin/customcss'),
+    custombehavior: require('./admin/custombehavior'),
     customlayout: require('./admin/customlayout'),
     userInvite: require('./admin/userInvite'),
     slackSetting: require('./admin/slackSetting'),

+ 6 - 0
lib/models/config.js

@@ -51,6 +51,7 @@ module.exports = function(crowi) {
       'plugin:isEnabledPlugins' : true,
 
       'customize:css' : '',
+      'customize:behavior' : 'crowi',
       'customize:layout' : 'crowi',
     };
   }
@@ -278,6 +279,11 @@ module.exports = function(crowi) {
     return this.uglifiedCustomCss;
   }
 
+  configSchema.statics.behaviorType = function(config)
+  {
+    return config.crowi['customize:behavior'] || 'crowi';
+  }
+
   configSchema.statics.layoutType = function(config)
   {
     return config.crowi['customize:layout'] || 'crowi';

+ 6 - 5
lib/routes/index.js

@@ -52,9 +52,10 @@ module.exports = function(crowi, app) {
   app.post('/admin/markdown/lineBreaksSetting', loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.markdown, admin.markdown.lineBreaksSetting);
 
   // markdown admin
-  app.get('/admin/customize'              , loginRequired(crowi, app) , middleware.adminRequired() , admin.customize.index);
-  app.post('/_api/admin/customize/css'    , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customcss, admin.api.customizeSetting);
-  app.post('/_api/admin/customize/layout' , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customlayout, admin.api.customizeSetting);
+  app.get('/admin/customize'                , loginRequired(crowi, app) , middleware.adminRequired() , admin.customize.index);
+  app.post('/_api/admin/customize/css'      , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customcss, admin.api.customizeSetting);
+  app.post('/_api/admin/customize/behavior' , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.custombehavior, admin.api.customizeSetting);
+  app.post('/_api/admin/customize/layout'   , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customlayout, admin.api.customizeSetting);
 
   // search admin
   app.get('/admin/search'              , loginRequired(crowi, app) , middleware.adminRequired() , admin.search.index);
@@ -139,7 +140,7 @@ module.exports = function(crowi, app) {
   app.post('/_/edit'                 , form.revision             , loginRequired(crowi, app) , csrf, page.pageEdit);
   app.get('/trash/$'                 , loginRequired(crowi, app, false) , page.deletedPageListShow);
   app.get('/trash/*/$'               , loginRequired(crowi, app, false) , page.deletedPageListShow);
-  app.get('/*/$'                     , loginRequired(crowi, app, false) , page.pageListShow);
-  app.get('/*'                       , loginRequired(crowi, app, false) , page.pageShow);
 
+  app.get('/*/$'                   , loginRequired(crowi, app, false) , page.pageListShowWrapper);
+  app.get('/*'                     , loginRequired(crowi, app, false) , page.pageShowWrapper);
 };

+ 146 - 1
lib/routes/page.js

@@ -4,6 +4,8 @@ module.exports = function(crowi, app) {
   var debug = require('debug')('crowi:routes:page')
     , Page = crowi.model('Page')
     , User = crowi.model('User')
+    , Config   = crowi.model('Config')
+    , config   = crowi.getConfig()
     , Revision = crowi.model('Revision')
     , Bookmark = crowi.model('Bookmark')
     , ApiResponse = require('../util/apiResponse')
@@ -61,12 +63,39 @@ module.exports = function(crowi, app) {
     };
   }
 
-  // routing
+  /**
+   * switch action by behaviorType
+   */
+  actions.pageListShowWrapper = function(req, res) {
+    const behaviorType = Config.behaviorType(config);
+
+    if ('crowi-plus' === behaviorType) {
+      return actions.pageListShowForCrowiPlus(req, res);
+    }
+    else {
+      return actions.pageListShow(req, res);
+    }
+  }
+  /**
+   * switch action by behaviorType
+   */
+  actions.pageShowWrapper = function(req, res) {
+    const behaviorType = Config.behaviorType(config);
+
+    if ('crowi-plus' === behaviorType) {
+      return actions.pageShowForCrowiPlus(req, res);
+    }
+    else {
+      return actions.pageShow(req, res);
+    }
+  }
+
   actions.pageListShow = function(req, res) {
     var path = getPathFromRequest(req);
     var limit = 50;
     var offset = parseInt(req.query.offset)  || 0;
     var SEENER_THRESHOLD = 10;
+    // add slash to the last
     path = path + (path == '/' ? '' : '/');
 
     debug('Page list show', path);
@@ -119,6 +148,122 @@ module.exports = function(crowi, app) {
     });
   };
 
+  actions.pageListShowForCrowiPlus = function(req, res) {
+    var path = getPathFromRequest(req);
+    // omit the slash of the last
+    path = path.replace((/\/$/), '');
+    // redirect
+    return res.redirect(path);
+  }
+
+  actions.pageShowForCrowiPlus = function(req, res) {
+    var path = getPathFromRequest(req);
+
+    var limit = 50;
+    var offset = parseInt(req.query.offset)  || 0;
+    var SEENER_THRESHOLD = 10;
+
+    // index page
+    var pagerOptions = {
+      offset: offset,
+      limit : limit
+    };
+    var queryOptions = {
+      offset: offset,
+      limit : limit + 1
+    };
+
+    var renderVars = {
+      path: path,
+      page: null,
+      revision: {},
+      author: false,
+      pages: [],
+      tree: [],
+    };
+
+    var pageTeamplate = 'customlayout-selector/page';
+
+    Page.findPage(path, req.user, req.query.revision)
+    .then(function(page) {
+      renderVars.page = page;
+
+      if (page) {
+        renderVars.path = page.path;
+        renderVars.revision = page.revision;
+        renderVars.author = page.revision.author;
+
+        return Revision.findRevisionList(page.path, {})
+        .then(function(tree) {
+          renderVars.tree = tree;
+          return Promise.resolve();
+        }).then(function() {
+          var userPage = isUserPage(page.path);
+          var userData = null;
+
+          if (userPage) {
+            // change template
+            pageTeamplate = 'customlayout-selector/user_page';
+
+            return User.findUserByUsername(User.getUsernameByPath(page.path))
+            .then(function(data) {
+              if (data === null) {
+                throw new Error('The user not found.');
+              }
+              userData = data;
+              renderVars.pageUser = userData;
+
+              return Bookmark.findByUser(userData, {limit: 10, populatePage: true, requestUser: req.user});
+            }).then(function(bookmarkList) {
+              renderVars.bookmarkList = bookmarkList;
+
+              return Page.findListByCreator(userData, {limit: 10}, req.user);
+            }).then(function(createdList) {
+              renderVars.createdList = createdList;
+              return Promise.resolve();
+            }).catch(function(err) {
+              debug('Error on finding user related entities', err);
+              // pass
+            });
+          }
+          else {
+            return Promise.resolve();
+          }
+        });
+      } else {
+        return Promise.resolve();
+      }
+    }).catch(function(err) {
+      // page not exists
+      // change template
+      pageTeamplate = 'crowi-plus/new_page';
+    }).then(function() {
+      return Page.findListByStartWith(path, req.user, queryOptions)
+        .then(function(pageList) {
+          if (pageList.length > limit) {
+            pageList.pop();
+          }
+
+          pagerOptions.length = pageList.length;
+
+          renderVars.viewConfig = {
+            seener_threshold: SEENER_THRESHOLD,
+          };
+          renderVars.pager = generatePager(pagerOptions);
+          renderVars.pages = pageList;
+
+          return Promise.resolve();
+        });
+    }).then(function() {
+      return interceptorManager.process('beforeRenderPage', req, res, renderVars);
+    }).then(function() {
+      res.render(req.query.presentation ? 'page_presentation' : pageTeamplate, renderVars);
+    }).catch(function(err) {
+      console.log(err);
+      debug('Error on rendering pageListShowForCrowiPlus', err);
+    });
+  }
+
   actions.deletedPageListShow = function(req, res) {
     var path = '/trash' + getPathFromRequest(req);
     var limit = 50;

+ 5 - 0
lib/util/swigFunctions.js

@@ -55,6 +55,11 @@ module.exports = function(crowi, app, req, locals) {
     return Config.customCss();
   }
 
+  locals.behaviorType = function() {
+    var config = crowi.getConfig()
+    return Config.behaviorType(config);
+  }
+
   locals.layoutType = function() {
     var config = crowi.getConfig()
     return Config.layoutType(config);

+ 47 - 1
lib/views/admin/customize.html

@@ -45,6 +45,52 @@
     </div>
     <div class="col-md-9">
 
+      <form action="/_api/admin/customize/behavior" method="post" class="form-horizontal" id="cutombehaviorSettingForm" role="form">
+      <fieldset>
+        <legend>挙動</legend>
+
+        <div class="form-group">
+          <div class="col-xs-6">
+            <h4>
+              <input type="radio" name="settingForm[customize:behavior]" value="crowi"
+                  {% if !settingForm['customize:behavior'] || 'crowi' === settingForm['customize:behavior'] %}checked="checked"{% endif %}>
+              Official Crowi Behavior
+            </h4>
+            <ul>
+              <li><code>/page</code> shows the page</li>
+              <li><code>/page/</code> shows the list of sub pages</li>
+              <ul>
+                <li>If portal is applied to <code>/page/</code> , the portal and the list of sub pages are shown</li>
+              </ul>
+              <li><code>/nonexistent_page</code> shows editing form</li>
+              <li><code>/nonexistent_page/</code> the list of sub pages</li>
+            </ul>
+          </div>
+          <div class="col-xs-6">
+            <h4>
+              <input type="radio" name="settingForm[customize:behavior]" value="crowi-plus"
+                  {% if 'crowi-plus' === settingForm['customize:behavior'] %}checked="checked"{% endif %}>
+              crowi-plus Simplified Behavior <small class="text-success">(Recommended)</small>
+            </h4>
+            <ul>
+              <li><code>/page</code> and <code>/page/</code> both shows the page</li>
+              <li><code>/nonexistent_page</code> shows editing form</li>
+              <li>All pages shows the list of sub pages</li>
+            </ul>
+          </div>
+        </div>
+
+        <div class="form-group">
+          <div class="col-xs-offset-5 col-xs-6">
+            <input type="hidden" name="_csrf" value="{{ csrf() }}">
+            <button type="submit" class="btn btn-primary">更新</button>
+          </div>
+        </div>
+
+      </fieldset>
+      </form>
+
+
       <form action="/_api/admin/customize/layout" method="post" class="form-horizontal" id="cutomlayoutSettingForm" role="form">
       <fieldset>
         <legend>レイアウト</legend>
@@ -133,7 +179,7 @@
   </div>
 
   <script>
-    $('#cutomcssSettingForm, #cutomlayoutSettingForm').each(function() {
+    $('#cutomcssSettingForm, #cutomlayoutSettingForm, #cutombehaviorSettingForm').each(function() {
       $(this).submit(function()
       {
         function showMessage(formId, msg, status) {

+ 120 - 0
lib/views/crowi-plus/new_page.html

@@ -0,0 +1,120 @@
+{% extends 'base/page_nosidebar.html' %}
+
+{% block main_css_class %}
+  main-crowi-plus-customized
+  {% parent %}
+{% endblock %}
+
+{% block content_head %}
+
+  {% block content_head_before %}
+  {% endblock %}
+
+  <div class="header-wrap">
+    <header id="page-header">
+      <p class="stopper"><a href="#" data-affix-disable="#page-header"><i class="fa fa-chevron-up"></i></a></p>
+
+      <div class="flex-title-line">
+        <div>
+          <h1 class="title flex-item-title" id="revision-path"></h1>
+          <div id="revision-url" class="url-line"></div>
+        </div>
+      </div>
+
+    </header>
+  </div>
+
+  {% block content_head_after %}
+  {% endblock %}
+
+{% endblock %} {# /content_head #}
+
+{% block content_main %}
+  <div class="container-fluid">
+    <div class="row">
+
+      <div class="col-lg-10 col-md-9">
+
+        {% block content_main_before %}
+        <h2 class="text-muted">Page is not exists</h2>
+        {% endblock %}
+
+
+
+        <div id="content-main" class="content-main content-main-new-page page-list"
+          data-path="{{ path }}"
+          data-path-shortname="{{ path|path2name }}"
+          data-page-id="{% if page %}{{ page._id.toString() }}{% endif %}"
+          data-current-user="{% if user %}{{ user._id.toString() }}{% endif %}"
+          data-current-username="{% if user %}{{ user.username }}{% endif %}"
+          data-page-revision-id="{% if revision %}{{ revision._id.toString() }}{% endif %}"
+          data-page-revision-created="{% if revision %}{{ revision.createdAt|datetz('U') }}{% endif %}"
+          data-page-is-seen="{% if page and page.isSeenUser(user) %}1{% else %}0{% endif %}"
+          data-linebreaks-enabled="{{ isEnabledLinebreaks() }}"
+          data-csrftoken="{{ csrf() }}"
+          >
+
+          <ul class="nav nav-tabs hidden-print">
+            <li class="active"><a href="#revision-body" data-toggle="tab">{{ t('List View') }}</a></li>
+
+            <li>
+              <a {% if user %}href="#edit-form" data-toggle="tab"{% endif %} class="edit-button {% if not user %}edit-button-disabled{% endif %}">
+                <i class="fa fa-pencil-square-o"></i> {{ t('Edit') }}
+              </a>
+            </li>
+
+            {% if user %}
+            <li class="dropdown pull-right">
+              <a href="#" onclick="history.back();"><i class="fa fa-times"></i> {{ t('Cancel') }}</a>
+            </li>
+            {% endif %}
+          </ul>
+
+          <div class="tab-content wiki-content">
+            {% if req.query.renamed %}
+            <div class="alert alert-info alert-moved">
+              <span>
+                <strong>{{ t('Moved') }}: </strong> {{ t('page_page.notice.moved', req.query.renamed) }}
+              </span>
+            </div>
+            {% endif %}
+            {% if req.query.unlinked %}
+            <div class="alert alert-info">
+              <strong>{{ t('Unlinked') }}: </strong> {{ t('page_page.notice.unlinked') }}
+            </div>
+            {% endif %}
+
+            {# list view #}
+            <div class="active tab-pane page-list-container" id="revision-body">
+              {% if pages.length == 0 %}
+                There are no pages under <strong>{{ path }}</strong>.
+              {% endif  %}
+
+              {% include '../widget/page_list.html' with { pages: pages, pager: pager, viewConfig: viewConfig } %}
+            </div>
+
+            {# edit view #}
+            <div class="edit-form tab-pane {% if req.body.pageForm %}active{% endif %}" id="edit-form">
+              {% include '../_form.html' %}
+            </div>
+
+          </div>
+        </div>
+
+        {% block content_main_after %}
+        {% endblock %}
+
+
+
+      </div> {# /.col- #}
+
+    </div>
+  </div>
+
+{% endblock %}
+
+{% block content_main_after %}
+{% endblock %}
+
+{% block content_footer %}
+{% endblock %}

+ 9 - 1
lib/views/crowi-plus/page.html

@@ -17,7 +17,6 @@
 
 {% endblock %} {# /content_head #}
 
-
 {% block content_main %}
   <div class="container-fluid">
     <div class="row">
@@ -39,6 +38,15 @@
       </div> {# /.col- #}
 
     </div>
+
+    {% if 'crowi-plus' === behaviorType() %}
+    <div class="row page-list">
+      <div class="col-md-12">
+        {% include './widget/page_list_container.html' %}
+      </div>
+    </div>
+    {% endif %}
+
   </div>
 {% endblock %}
 

+ 34 - 0
lib/views/crowi-plus/widget/page_list_container.html

@@ -0,0 +1,34 @@
+<div class="page-list-container">
+  <ul class="nav nav-tabs">
+      <li class="active"><a href="#view-list" data-toggle="tab">{{ t('List View') }}</a></li>
+      <li><a href="#view-timeline" data-toggle="tab">{{ t('Timeline View') }}</a></li>
+  </ul>
+
+  <div class="tab-content">
+    {% if pages.length == 0 %}
+
+      {% if isTrashPage() %}
+      No deleted pages.
+      {% else %}
+      There are no pages under <strong>{{ path }}</strong>.
+      {% endif %}
+    {% endif  %}
+
+    {# list view #}
+    <div class="active tab-pane fade page-list-container in" id="view-list">
+      {% include '../../widget/page_list.html' with { pages: pages, pager: pager, viewConfig: viewConfig } %}
+    </div>
+
+    {# timeline view #}
+    <div class="tab-pane" id="view-timeline" data-shown=0>
+      {% for page in pages %}
+      <div class="timeline-body" id="id-{{ page.id }}">
+        <h3 class="revision-path"><a href="{{ page.path }}">{{ page.path }}</a></h3>
+        <div class="revision-body wiki"></div>
+        <script type="text/template">{{ page.revision.body }}</script>
+      </div>
+      <hr>
+      {% endfor %}
+    </div>
+  </div>
+</div>

+ 1 - 0
resource/css/_layout.scss

@@ -69,6 +69,7 @@
 
       .header-wrap {
         padding: 16px 16px 0 16px;
+        min-height: 70px;
       }
 
       .content-main {

+ 6 - 0
resource/css/_page_crowi-plus.scss

@@ -34,3 +34,9 @@
     }
   }
 }
+
+.crowi-plus .content-main-new-page {
+  .nav {
+    margin-top: 30px;
+  }
+}

+ 2 - 2
resource/js/legacy/crowi.js

@@ -213,7 +213,7 @@ $(function() {
     if (input2 === '') {
       prefix2 = prefix2.slice(0, -1);
     }
-    top.location.href = prefix1 + input1 + prefix2 + input2;
+    top.location.href = prefix1 + input1 + prefix2 + input2 + '#edit-form';
     return false;
   });
 
@@ -225,7 +225,7 @@ $(function() {
     if (name.match(/.+\/$/)) {
       name = name.substr(0, name.length - 1);
     }
-    top.location.href = name;
+    top.location.href = name + '#edit-form';
     return false;
   });