Browse Source

[search] UX improvements for the admin section

Removed unused files and classes
Moved css from global to app
Restyled tables and page titles
Added linking to edit index from dashboard
Improved consistency of object naming
Fixed breadcrum typo
Enrico Berti 11 years ago
parent
commit
cca5aec

+ 38 - 37
apps/search/src/search/templates/admin_collections.mako

@@ -27,29 +27,28 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
 <link rel="stylesheet" href="/search/static/css/admin.css">
 
 <div class="search-bar" style="height: 30px">
-    <div class="pull-right" style="margin-right: 20px">
+  <div class="pull-right">
     <a class="btn importBtn" href="${ url('indexer:collections') }">
       <i class="fa fa-database"></i> ${ _('Indexes') }
     </a>
-    </div>
-  <h4><a href="">${_('Dashboards')}</a></h4>
+  </div>
+  <h4><i class="fa fa-tags"></i> ${_('Dashboards')}</h4>
 </div>
 
 <div class="container-fluid">
-  <div class="card">
+  <div class="card card-home card-small">
     <%actionbar:render>
       <%def name="search()">
         <input type="text" placeholder="${_('Filter dashboards...')}" class="input-xlarge search-query" id="filterInput" data-bind="visible: collections().length > 0 && !isLoading()">
-        &nbsp;
-        &nbsp;
-        <span>
-          <a class="btn" data-bind="click: $root.copyCollections, clickBubble: false"><i class="fa fa-files-o"></i> ${_('Copy')}</a> &nbsp;&nbsp;
-          <a class="btn" data-bind="click: $root.markManyForDeletion, clickBubble: false"><i class="fa fa-times"></i> ${_('Delete')}</a>
-        </span>
-        <a data-bind="visible: collections().length > 0 && !isLoading()" class="btn pull-right" href="${ url('search:new_search') }" title="${ _('Create a new dashboard') }"><i class="fa fa-plus-circle"></i> ${ _('Dashboard') }</a>
+      </%def>
+
+      <%def name="actions()">
+        <a class="btn" data-bind="click: $root.copyCollections, clickBubble: false"><i class="fa fa-files-o"></i> ${_('Copy')}</a>
+        <a class="btn" data-bind="click: $root.markManyForDeletion, clickBubble: false"><i class="fa fa-times"></i> ${_('Delete')}</a>
       </%def>
 
       <%def name="creation()">
+        <a data-bind="visible: collections().length > 0 && !isLoading()" class="btn" href="${ url('search:new_search') }" title="${ _('Create a new dashboard') }"><i class="fa fa-plus-circle"></i> ${ _('Create') }</a>
       </%def>
     </%actionbar:render>
 
@@ -72,28 +71,30 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
     </div>
 
     <div class="row-fluid" data-bind="visible: collections().length > 0 && !isLoading()">
-      <table class="table table-condensed">
-        <thead>
-          <tr>
-            <th>
-              <span data-bind="click: toggleSelectAll, css: {'fa-check': !ko.utils.arrayFilter(filteredCollections(), function(collection) {return !collection.selected()}).length}" class="hueCheckbox fa"></span>
-            </th>
-            <th>${ _('Name') }</th>
-            <th>${ _('Solr Index') }</th>
-            <th class="center">${ _('Shared') }</th>
-          </tr>
-        </thead>
-        <tbody data-bind="foreach: filteredCollections">
-          <tr>
-            <td data-bind="click: $root.toggleCollectionSelect.bind($root), clickBubble: false">
-              <span data-bind="css: {'fa-check': $root.filteredCollections()[$index()].selected()}" class="hueCheckbox fa"></span>
-            </td>
-            <td><a data-bind="text: label, click: $root.editCollection" title="${ _('Click to edit') }" class="pointer"></a></td>
-            <td data-bind="text: name"></td>
-            <td class="center"><span data-bind="css: { 'fa fa-check': enabled }"></span></td>
-          </tr>
-        </tbody>
-      </table>
+      <div class="span12">
+        <table class="table table-condensed">
+          <thead>
+            <tr>
+              <th style="width: 1%">
+                <span data-bind="click: toggleSelectAll, css: {'fa-check': !ko.utils.arrayFilter(filteredCollections(), function(collection) {return !collection.selected()}).length}" class="hueCheckbox fa"></span>
+              </th>
+              <th>${ _('Name') }</th>
+              <th>${ _('Solr Index') }</th>
+              <th width="1%" class="center">${ _('Shared') }</th>
+            </tr>
+          </thead>
+          <tbody data-bind="foreach: filteredCollections">
+            <tr>
+              <td data-bind="click: $root.toggleCollectionSelect.bind($root), clickBubble: false">
+                <span data-bind="css: {'fa-check': $root.filteredCollections()[$index()].selected()}" class="hueCheckbox fa"></span>
+              </td>
+              <td><a data-bind="text: label, click: $root.editCollection" title="${ _('Click to edit') }" class="pointer"></a></td>
+              <td><a data-bind="text: name, click: $root.editIndex" title="${ _('Click to edit the index') }" class="pointer"></a></td>
+              <td class="center"><span data-bind="css: { 'fa fa-check': enabled }"></span></td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
     </div>
   </div>
 </div>
@@ -113,7 +114,7 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
     <h3>${_('Confirm Delete')}</h3>
   </div>
   <div class="modal-body">
-    <p>${_('Are you sure you want to delete the selected collections?')}</p>
+    <p>${_('Are you sure you want to delete the selected dashboards?')}</p>
   </div>
   <div class="modal-footer">
     <a class="btn" data-dismiss="modal">${ _('No') }</a>
@@ -131,7 +132,7 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
     listCollectionsUrl: "${ url("search:admin_collections") }?format=json",
     deleteUrl: "${ url("search:admin_collection_delete") }",
     copyUrl: "${ url("search:admin_collection_copy") }",
-    indexerUrl: "/indexer/#edit/"
+    indexerUrl: "/indexer/#link/"
   }
 
   var viewModel = new SearchCollectionsModel(appProperties);
@@ -171,11 +172,11 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
     $(document).on("collectionDeleted", function () {
       $("#deleteModal").modal("hide");
       $("#deleteModalBtn").button("reset");
-      $(document).trigger("info", "${ _("Collection deleted successfully.") }");
+      $(document).trigger("info", "${ _("Dashboard deleted successfully.") }");
     });
 
     $(document).on("collectionCopied", function () {
-      $(document).trigger("info", "${ _("Collection copied successfully.") }");
+      $(document).trigger("info", "${ _("Dashboard copied successfully.") }");
     });
 
     $(document).on("confirmDelete", function () {

+ 0 - 103
apps/search/src/search/templates/layout.mako

@@ -1,103 +0,0 @@
-## Licensed to Cloudera, Inc. under one
-## or more contributor license agreements.  See the NOTICE file
-## distributed with this work for additional information
-## regarding copyright ownership.  Cloudera, Inc. licenses this file
-## to you under the Apache License, Version 2.0 (the
-## "License"); you may not use this file except in compliance
-## with the License.  You may obtain a copy of the License at
-##
-##     http://www.apache.org/licenses/LICENSE-2.0
-##
-## Unless required by applicable law or agreed to in writing, software
-## distributed under the License is distributed on an "AS IS" BASIS,
-## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-## See the License for the specific language governing permissions and
-## limitations under the License.
-
-<%!
-  from django.utils.translation import ugettext as _
-%>
-
-<%namespace name="utils" file="utils.inc.mako" />
-
-<%def name="skeleton()">
-  <link rel="stylesheet" href="/search/static/css/admin.css">
-  <link rel="stylesheet" href="/static/ext/chosen/chosen.min.css">
-  <script src="/static/ext/chosen/chosen.jquery.min.js" type="text/javascript" charset="utf-8"></script>
-  <script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
-
-  <div class="search-bar" style="height: 30px">
-    % if not hasattr(caller, "no_navigation"):
-      <div class="pull-right" style="margin-top: 4px; margin-right: 20px">
-        <a href="${ url('search:index') }?collection=${ hue_collection.id }"><i class="fa fa-share"></i> ${ _('Search page') }</a> &nbsp; &nbsp;
-        <a href="${ url('search:admin_collections') }"><i class="fa fa-sitemap"></i> ${ _('Collection manager') }</a>
-      </div>
-    % endif
-
-    % if hasattr(caller, "title"):
-      ${ caller.title() }
-    % else:
-        <h4>${ _('Search Admin') }</h4>
-    % endif
-  </div>
-
-  <div class="container-fluid">
-
-    <div class="row-fluid">
-      %if hasattr(caller, "navigation"):
-          <div class="span2">
-            ${caller.navigation()}
-          </div>
-
-          <div class="span10">
-            %if hasattr(caller, "content"):
-              ${caller.content()}
-            %endif
-          </div>
-      %else:
-        <div class="span12">
-          %if hasattr(caller, "content"):
-              ${caller.content()}
-          %endif
-        </div>
-      %endif
-    </div>
-  </div>
-  <script type="text/javascript">
-    $(document).ready(function () {
-      $("#change-collection").change(function(){
-        location.href = $("#change-collection").val();
-      });
-    });
-  </script>
-</%def>
-
-<%def name="sidebar(hue_collection, section='')">
-  <div class="sidebar-nav" style="min-height: 250px">
-    <ul class="nav nav-list">
-
-    <li class="nav-header">${_('Collection')}</li>
-      <li class="${ utils.is_selected(section, 'properties') }">
-        <a href="${ url('search:admin_collection_properties', collection_id=hue_collection.id) }"><i class="fa fa-list"></i> ${_('Properties')}</a>
-      </li>
-      <li>
-        <a href="${ url('search:index') }?collection=${ hue_collection.id }"><i class="fa fa-search"></i> ${ _('Search it') }</a>
-      </li>
-
-      <li class="nav-header">${_('Template')}</li>
-      <li class="${ utils.is_selected(section, 'template') }">
-        <a href="${ url('search:admin_collection_template', collection_id=hue_collection.id) }">${_('1. Snippet')}</a>
-      </li>
-      <li class="${ utils.is_selected(section, 'facets') }">
-        <a href="${ url('search:admin_collection_facets', collection_id=hue_collection.id) }">${_('2. Facets')}</a>
-      </li>
-      <li class="${ utils.is_selected(section, 'sorting') }">
-        <a href="${ url('search:admin_collection_sorting', collection_id=hue_collection.id) }">${_('3. Sorting')}</a>
-      </li>
-      <li class="${ utils.is_selected(section, 'highlighting') }">
-        <a href="${ url('search:admin_collection_highlighting', collection_id=hue_collection.id) }">${_('4. Highlighting')}</a>
-      </li>
-
-    </ul>
-  </div>
-</%def>

+ 22 - 116
apps/search/static/css/admin.css

@@ -15,69 +15,6 @@
  See the License for the specific language governing permissions and
  limitations under the License.
 */
-
-h3 {
-  line-height: 24px;
-}
-
-.sidebar-nav {
-  padding: 9px 0;
-}
-
-#content-editor {
-  border: 1px dotted #DDD;
-}
-
-.available-fields {
-  padding: 0;
-  padding-left:10px;
-}
-
-.available-fields ul {
-  list-style: none outside none;
-  padding: 0;
-  margin: 0;
-  cursor: pointer;
-}
-
-.available-fields ul li {
-  cursor: pointer;
-  color: #666;
-}
-
-.form-actions {
-  padding-left: 0!important;
-}
-
-.bubble {
-  float: left;
-  background-color: #EEEEEE;
-  border: 1px solid #E0E0E0;
-  padding: 8px;
-  margin: 4px;
-  -webkit-border-radius: 4px;
-  -moz-border-radius: 4px;
-  border-radius: 4px;
-}
-
-.section {
-  background-color: #FAFAFA;
-  -webkit-border-radius: 4px;
-  -moz-border-radius: 4px;
-  border-radius: 4px;
-}
-
-.miniform {
-  margin-top: 20px;
-  background-color: #F3F3F3;
-  padding: 10px;
-  border-top: 1px solid #DDD;
-}
-
-.select-mini {
-  width: 100%;
-}
-
 .search-bar {
   background-color: #fafafa;
   border-bottom: 1px solid #e3e3e3;
@@ -93,65 +30,34 @@ h3 {
 }
 
 .search-bar h4 {
-  margin-top: 4px;
-}
-
-.waiting {
-  font-size: 196px;
-  color: #DDD;
+  font-size: 20px !important;
+  color: #338BB8 !important;
+  padding: 0 !important;
+  margin-top: 4px !important;
+  margin-left: 20px;
+  border: none !important;
+  max-width: none!important;
 }
 
-h1.emptyMessage {
-  margin-top: 50px;
-  color: #BBB;
-  line-height: 60px;
-}
-
-.stepDetails {
-  padding: 5px;
-}
-
-.editable {
-  cursor: pointer;
-}
-
-.collectionRow {
-  cursor: pointer;
-  margin-bottom: 10px;
-  padding: 10px;
-  height: 40px;
-}
-
-.collectionRow:hover {
-  background-color: #EFEFEF;
-}
-
-.hue-colorchart {
+#collections {
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
   width: 100%;
 }
 
-.hue-colorchart td {
-  padding: 4px;
-  cursor: pointer;
-}
-
-.cloud-tmpl {
-  border: 1px dashed #FFFFFF;
-  padding: 10px;
-  margin-bottom: 10px;
-  color: #666;
-  cursor: pointer;
-}
-
-.cloud-tmpl h4 {
-  margin-top: 0;
+.coll-heading {
+  position: relative;
+  top: 10px;
 }
 
-.cloud-tmpl.selected {
-  border: 1px dashed #338BB8;
+.placeholder {
+  background-color: #F5F5F5;
+  border: 1px solid #E3E3E3;
+  height: 40px;
 }
 
-.cloud-tmpl:hover, .cloud-tmpl.selected:hover  {
-  color: #000;
-  border: 1px dashed #CCCCCC;
-}
+.collection-actions {
+   cursor: pointer;
+   margin: 10px 10px 0 0;
+ }

+ 4 - 6
apps/search/static/js/collections.ko.js

@@ -105,17 +105,15 @@ var SearchCollectionsModel = function (props) {
     }));
   };
 
-  self.viewIndex = function (collection) {
-    var idx = [self.INDEXER_URL, collection.label()].join('');
-    cleanCollections();
-    location.href = idx;
-  };
-
   self.editCollection = function (collection) {
     cleanCollections();
     location.href = collection.absoluteUrl();
   };
 
+  self.editIndex = function (collection) {
+    location.href = self.INDEXER_URL + collection.name();
+  };
+
   self.markManyForDeletion = function (collections) {
     self.collectionToDelete = collections;
     $(document).trigger("confirmDelete")

+ 8 - 43
desktop/core/static/css/hue3.css

@@ -1266,12 +1266,6 @@ a#advanced-btn:hover {
   z-index: 9999;
 }
 
-
-.card table {
-  padding-left: 10px;
-  padding-right: 10px;
-}
-
 .tooltip {
   border: 0;
   z-index: 1032;
@@ -1671,46 +1665,17 @@ border-bottom-left-radius: 0px;
   height: 24px;
 }
 
-/*********************************************************
- *
- * Styles from admin_collections.mako template
- *
- ********************************************************/
-
-#collections {
-  list-style-type: none;
-  margin: 0;
-  padding: 0;
-  width: 100%;
-}
-
-.coll-heading {
-  position: relative;
-  top: 10px;
-}
-
-.placeholder {
-  background-color: #F5F5F5;
-  border: 1px solid #E3E3E3;
-  height: 40px;
-}
-
-.collection-actions {
-   cursor: pointer;
-   margin: 10px 10px 0 0;
- }
-
 /*********************************************************
  *
  * Misc styles that can be reused as needed
  * - from admin_collections.mako template
  *
  ********************************************************/
- .spinner {
-   color: #ddd;
-   font-size: 60px;
- }
-
- .pointer {
-   cursor: pointer;
- }
+.spinner {
+ color: #ddd;
+ font-size: 60px;
+}
+
+.pointer {
+ cursor: pointer;
+}

+ 42 - 35
desktop/libs/indexer/src/indexer/templates/collections.mako

@@ -22,7 +22,7 @@
 <%namespace name="macros" file="macros.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 
-${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
+${ commonheader(_('Search Indexes'), "indexer", user, "29px") | n,unicode }
 
 <link rel="stylesheet" href="/static/ext/chosen/chosen.min.css">
 <link rel="stylesheet" href="/indexer/static/css/admin.css">
@@ -57,12 +57,12 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
 
 
 <div class="search-bar" style="height: 30px">
-  <div class="pull-right" style="margin-right: 20px">
+  <div class="pull-right">
     <a class="btn importBtn" href="${ url('search:admin_collections') }" title="${ _('Collections') }" rel="tooltip" data-placement="bottom" data-bind="css: {'btn': true}">
       <i class="fa fa-tags"></i> ${ _('Dashboards') }
     </a>
   </div>
-  <h4><a href="#manage">${_('Solr Indexer')}</a></h4>
+  <h4><a href="#manage"><i class="fa fa-database"></i> ${_('Indexes')}</a></h4>
 </div>
 
 <div class="container-fluid">
@@ -99,7 +99,7 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
 <div data-bind="with: manage" id="deleteCollections" class="modal hide fade">
   <div class="modal-header">
     <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Delete collections')}</h3>
+    <h3>${_('Delete indexes')}</h3>
   </div>
   <div class="modal-body">
     <ul data-bind="foreach: selectedCloudCollections">
@@ -116,7 +116,7 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
 <div data-bind="with: edit" id="deleteCollection" class="modal hide fade">
   <div data-bind="if: collection()" class="modal-header">
     <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Delete collection ')} <span data-bind="text: collection().name"></span></h3>
+    <h3>${_('Delete index ')} <span data-bind="text: collection().name"></span></h3>
   </div>
   <div class="modal-body"></div>
   <div data-bind="if: collection()" class="modal-footer">
@@ -126,36 +126,35 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
 </div>
 
 
-<!-- Breadcrum component -->
-<script id="breadcrum" type="text/html">
-<ul data-bind="foreach: breadcrum.list" class="nav nav-pills hueBreadcrumbBar">
+<!-- breadcrumb component -->
+<script id="breadcrumb" type="text/html">
+<ul data-bind="foreach: breadcrumb.list" class="nav nav-pills hueBreadcrumbBar">
   <li class="nowrap">
-    <!-- ko if: $index() == ( $root.breadcrum.list().length - 1 ) -->
+    <!-- ko if: $index() == ( $root.breadcrumb.list().length - 1 ) -->
     <span data-bind="text: label" style="padding-left:12px"></span>
     <!-- /ko -->
-    <!-- ko if: $index() != ( $root.breadcrum.list().length - 1 ) -->
+    <!-- ko if: $index() != ( $root.breadcrumb.list().length - 1 ) -->
     <a data-bind="routie: url, text: label" href="javascript:void(0)"></a>
     <span class="divider">&gt;</span>
     <!-- /ko -->
   </li>
 </ul>
 </script>
-<!-- /Breadcrum component -->
+<!-- /breadcrumb component -->
 
 
 <!-- Manage collections page -->
 <script id="manage-page" type="text/html">
 <div class="span12" >
-  <div class="card wizard">
-    <div class="card-heading simple" data-bind="template: { 'name': 'breadcrum', 'data': $root, 'if': manage.collections().length != 0 }"></div>
-    <div class="card-body" data-bind="with: manage">
+  <div class="card card-home card-small wizard">
+    <div data-bind="with: manage">
       <%actionbar:render>
         <%def name="search()">
           <div data-bind="visible: collections().length > 0 && !isLoading()">
             <input type="text" data-bind="filter: { 'list': collections, 'filteredList': filteredCollections, 'test': filterTest }"
-                placeholder="${_('Filter collections...')}" class="input-xlarge search-query">
+                placeholder="${_('Filter indexes...')}" class="input-xlarge search-query">
             <button data-bind="clickBubble: false, disable: selectedCloudCollections().length == 0" class="btn toolbarBtn"
-                title="${_('Delete the selected collections. These must be solr cloud collections. Cores cannot be deleted currently.')}" data-toggle="modal" data-target="#deleteCollections">
+                title="${_('Delete the selected indexes. These must be solr cloud collections. Cores cannot be deleted currently.')}" data-toggle="modal" data-target="#deleteCollections">
               <i class="fa fa-times"></i> ${_('Delete')}
             </button>
             <a href="#create" class="btn toolbarBtn pull-right">
@@ -170,7 +169,7 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
       <div class="row-fluid" data-bind="visible: collections().length == 0 && !isLoading()">
         <div class="span10 offset1 center importBtn" style="cursor: pointer">
           <i class="fa fa-plus-circle waiting"></i>
-          <h1 class="emptyMessage">${ _('There are currently no collections defined.') }<br/><a href="#create">${ _('Click here to add') }</a> ${ _('one or more.') }</h1>
+          <h1 class="emptyMessage">${ _('There are currently no indexes defined.') }<br/><a href="#create">${ _('Click here to add') }</a> ${ _('one or more.') }</h1>
         </div>
       </div>
       <div class="row-fluid" data-bind="visible: collections().length > 0 && !isLoading()">
@@ -204,8 +203,8 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
 <!-- Create by file -->
 <script id="create-page" type="text/html">
 <div class="span12">
-  <div class="card wizard">
-    <div class="card-heading simple" data-bind="template: { 'name': 'breadcrum', 'data': $root }"></div>
+  <div class="card card-home card-small wizard">
+    <div class="card-heading simple" data-bind="template: { 'name': 'breadcrumb', 'data': $root }"></div>
     <div class="card-body" data-bind="with: create">
       <form data-bind="if: wizard.currentPage()" class="form form-horizontal">
         <div data-bind="template: { 'name': wizard.currentPage().name, 'afterRender': afterRender}"></div>
@@ -228,7 +227,7 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
   <div class="control-group" data-bind="css: {'error': collection.name.errors().length > 0}">
     <label for="name" class="control-label">${_("Name")}</label>
     <div class="controls">
-      <input data-bind="value: collection.name" name="name" type="text" placeholder="${_('Name of collection')}" />
+      <input data-bind="value: collection.name" name="name" type="text" placeholder="${_('Name of index')}" />
     </div>
   </div>
 
@@ -351,8 +350,8 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
   </div>
 </div>
 <div class="span9">
-  <div class="card wizard">
-    <div class="card-heading simple" data-bind="template: { 'name': 'breadcrum', 'data': $root }"></div>
+  <div class="card card-home card-small wizard">
+    <div class="card-heading simple" data-bind="template: { 'name': 'breadcrumb', 'data': $root }"></div>
     <div data-bind="with: edit"  class="card-body">
       <form class="form">
         <table class="table">
@@ -406,8 +405,8 @@ ${ commonheader(_('Collection Manager'), "indexer", user, "29px") | n,unicode }
 <!-- Upload wizard -->
 <script id="upload-page" type="text/html">
 <div class="span12">
-  <div class="card wizard">
-    <div class="card-heading simple" data-bind="template: { 'name': 'breadcrum', 'data': $root }"></div>
+  <div class="card card-home card-small wizard">
+    <div class="card-heading simple" data-bind="template: { 'name': 'breadcrumb', 'data': $root }"></div>
     <div class="card-body" data-bind="with: edit">
       <form data-bind="if: wizard.currentPage()" class="form form-horizontal">
         <div data-bind="template: { 'name': wizard.currentPage().name, 'afterRender': afterRender}"></div>
@@ -514,9 +513,9 @@ function validateFields(collection) {
 }
 
 var vm = new CollectionsViewModel({
-  'breadcrum': {
+  'breadcrumb': {
     'labels': {
-      '': "${_('Collections')}",
+      '': "${_('Indexes')}",
       'data': "${_('Upload data')}"
     },
     'skip': ['manage', 'upload', 'edit', 'create', 'wizard']
@@ -543,27 +542,35 @@ vm.edit.sourceType.subscribe(function(value) {
 
 routie({
   "": function() {
-    vm.breadcrum("manage");
+    vm.breadcrumb("manage");
     vm.page('manage-page');
   },
   "manage": function() {
-    vm.breadcrum(window.location.hash.substring(1));
+    vm.breadcrumb(window.location.hash.substring(1));
     vm.page('manage-page');
   },
   "create": function() {
     vm.page('create-page');
-    vm.breadcrum("create/wizard/" + vm.create.wizard.currentPage().url());
+    vm.breadcrumb("create/wizard/" + vm.create.wizard.currentPage().url());
   },
   "create/wizard": function() {
     vm.page('create-page');
-    vm.breadcrum("create/wizard/" + vm.create.wizard.currentPage().url());
+    vm.breadcrumb("create/wizard/" + vm.create.wizard.currentPage().url());
   },
   "create/wizard/:step": function(step) {
-    vm.breadcrum(window.location.hash.substring(1));
+    vm.breadcrumb(window.location.hash.substring(1));
     vm.page('create-page');
     vm.create.wizard.setPageByUrl(step);
     routie('create/wizard/' + vm.create.wizard.currentPage().url());
   },
+  "link/:name": function(name) {
+    var _interval = window.setInterval(function(){
+      if (vm.manage.hasLoadedOnce()){
+        window.clearInterval(_interval);
+        routie("edit/"+name);
+      }
+    }, 300);
+  },
   "edit/:name": function(name) {
     ko.utils.arrayForEach(vm.manage.collections(), function(collection) {
       collection.selected(ko.unwrap(collection).name() == name);
@@ -571,7 +578,7 @@ routie({
     if (vm.manage.selectedCollections().length == 0) {
       routie('manage');
     } else {
-      vm.breadcrum(window.location.hash.substring(1));
+      vm.breadcrumb(window.location.hash.substring(1));
       vm.edit.collection(vm.manage.selectedCollections()[0]());
       vm.edit.fetchFields();
       vm.page('edit-page');
@@ -584,7 +591,7 @@ routie({
     if (vm.manage.selectedCollections().length == 0) {
       routie('manage');
     } else {
-      vm.breadcrum('edit/' + name + '/upload/' + vm.edit.wizard.currentPage().url());
+      vm.breadcrumb('edit/' + name + '/upload/' + vm.edit.wizard.currentPage().url());
       vm.edit.collection(vm.manage.selectedCollections()[0]());
       vm.page('upload-page');
     }
@@ -596,7 +603,7 @@ routie({
     if (vm.manage.selectedCollections().length == 0) {
       routie('manage');
     } else {
-      vm.breadcrum(window.location.hash.substring(1));
+      vm.breadcrumb(window.location.hash.substring(1));
       vm.edit.collection(vm.manage.selectedCollections()[0]());
       vm.page('upload-page');
     }
@@ -606,8 +613,8 @@ routie({
 });
 
 vm.manage.fetchCollections();
-
 ko.applyBindings(vm);
+
 </script>
 
 ${ commonfooter(messages) | n,unicode }

+ 7 - 1
desktop/libs/indexer/static/css/admin.css

@@ -93,7 +93,13 @@ h3 {
 }
 
 .search-bar h4 {
-  margin-top: 4px;
+  font-size: 20px !important;
+  color: #338BB8 !important;
+  padding: 0 !important;
+  margin-top: 4px !important;
+  margin-left: 20px;
+  border: none !important;
+  max-width: none!important;
 }
 
 .waiting {

+ 9 - 7
desktop/libs/indexer/static/js/collections.js

@@ -406,6 +406,7 @@ var ManageCollectionsViewModel = function() {
 
   // UI
   self.isLoading = ko.observable();
+  self.hasLoadedOnce = ko.observable(false);
   self.filteredCollections = ko.observableArray();
   self.selectedCollections = ko.computed(function() {
     return ko.utils.arrayFilter(self.collections(), function(collection) {
@@ -465,6 +466,7 @@ var ManageCollectionsViewModel = function() {
           collections.push(new_collection);
         });
         self.collections(collections);
+        self.hasLoadedOnce(true);
       } else {
         $(document).trigger("error", data.message);
       }
@@ -523,9 +525,9 @@ var CollectionsViewModel = function(config) {
 
   // Models
   self.page = ko.observable();
-  self.breadcrum = ko.observable();
-  self.breadcrum.list = ko.computed(function() {
-    var breadcrum_config = _config.breadcrum || {};
+  self.breadcrumb = ko.observable();
+  self.breadcrumb.list = ko.computed(function() {
+    var breadcrum_config = _config.breadcrumb || {};
     var labels = breadcrum_config.labels || {};
     var skip = breadcrum_config.skip || [];
     var breadcrums = [];
@@ -535,9 +537,9 @@ var CollectionsViewModel = function(config) {
       'label': labels[crum] || crum,
       'crum': crum
     });
-    if (self.breadcrum()) {
+    if (self.breadcrumb()) {
       var crums = [];
-      var newcrums = ko.utils.arrayMap( self.breadcrum().split('/'), function(crum) {
+      var newcrums = ko.utils.arrayMap( self.breadcrumb().split('/'), function(crum) {
         crums.push(crum);
         if (skip.indexOf(crum) != -1) {
           return null;
@@ -548,8 +550,8 @@ var CollectionsViewModel = function(config) {
           'crum': crum
         };
       });
-      breadcrums.push.apply( breadcrums, ko.utils.arrayFilter(newcrums, function(breadcrum) {
-        return !!breadcrum;
+      breadcrums.push.apply( breadcrums, ko.utils.arrayFilter(newcrums, function(breadcrumb) {
+        return !!breadcrumb;
       }) );
     }
     return breadcrums;