search.mako 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015
  1. ## Licensed to Cloudera, Inc. under one
  2. ## or more contributor license agreements. See the NOTICE file
  3. ## distributed with this work for additional information
  4. ## regarding copyright ownership. Cloudera, Inc. licenses this file
  5. ## to you under the Apache License, Version 2.0 (the
  6. ## "License"); you may not use this file except in compliance
  7. ## with the License. You may obtain a copy of the License at
  8. ##
  9. ## http://www.apache.org/licenses/LICENSE-2.0
  10. ##
  11. ## Unless required by applicable law or agreed to in writing, software
  12. ## distributed under the License is distributed on an "AS IS" BASIS,
  13. ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ## See the License for the specific language governing permissions and
  15. ## limitations under the License.
  16. <%!
  17. from desktop.views import commonheader, commonfooter
  18. from django.utils.translation import ugettext as _
  19. %>
  20. ${ commonheader(_('Search'), "search", user, "80px") | n,unicode }
  21. <script type="text/javascript">
  22. if (window.location.hash != "") {
  23. if (window.location.hash.indexOf("collection") > -1) {
  24. location.href = "/search/?" + window.location.hash.substr(1);
  25. }
  26. }
  27. </script>
  28. <div class="search-bar">
  29. <div class="pull-right" style="padding-right:50px">
  30. % if user.is_superuser:
  31. <button type="button" title="${ _('Edit') }" rel="tooltip" data-placement="bottom" data-bind="click: toggleEditing, css: {'btn': true, 'btn-inverse': isEditing}"><i class="fa fa-pencil"></i></button>
  32. <button type="button" title="${ _('Save') }" rel="tooltip" data-placement="bottom" data-loading-text="${ _("Saving...") }" data-bind="click: save, css: {'btn': true}"><i class="fa fa-save"></i></button>
  33. <button type="button" title="${ _('Settings') }" rel="tooltip" data-placement="bottom" data-toggle="modal" data-target="#settingsDemiModal"
  34. data-bind="css: {'btn': true}">
  35. <i class="fa fa-cog"></i>
  36. </button>
  37. % endif
  38. <button type="button" title="${ _('Share') }" rel="tooltip" data-placement="bottom" data-bind="click: showShareModal, css: {'btn': true}"><i class="fa fa-link"></i></button>
  39. % if user.is_superuser:
  40. &nbsp;&nbsp;&nbsp;
  41. <a class="btn" href="${ url('search:new_search') }" title="${ _('New') }" rel="tooltip" data-placement="bottom" data-bind="css: {'btn': true}"><i class="fa fa-file-o"></i></a>
  42. <a class="btn" href="${ url('search:admin_collections') }" title="${ _('Collections') }" rel="tooltip" data-placement="bottom" data-bind="css: {'btn': true}"><i class="fa fa-tags"></i></a>
  43. % endif
  44. </div>
  45. <form data-bind="visible: columns().length == 0">
  46. ${ _('Select a search index') }
  47. <!-- ko if: columns().length == 0 -->
  48. <select data-bind="options: $root.initial.collections, value: $root.collection.name">
  49. </select>
  50. <!-- /ko -->
  51. </form>
  52. <form class="form-search" style="margin: 0" data-bind="submit: searchBtn, visible: columns().length != 0">
  53. <strong>${_("Search")}</strong>
  54. <div class="input-append">
  55. <div class="selectMask">
  56. <span
  57. data-bind="editable: collection.label, editableOptions: {enabled: $root.isEditing(), placement: 'right'}">
  58. </span>
  59. </div>
  60. <span data-bind="foreach: query.qs">
  61. <input data-bind="clearable: q" maxlength="256" type="text" class="search-query input-xlarge">
  62. <!-- ko if: $index() >= 1 -->
  63. <a class="btn" href="javascript:void(0)" data-bind="click: $root.query.removeQ"><i class="fa fa-minus"></i></a>
  64. <!-- /ko -->
  65. </span>
  66. <a class="btn" href="javascript:void(0)" data-bind="click: $root.query.addQ"><i class="fa fa-plus"></i></a>
  67. <button type="submit" id="search-btn" class="btn btn-inverse" style="margin-left:10px"><i class="fa fa-search"></i></button>
  68. </div>
  69. </form>
  70. </div>
  71. <div class="card card-toolbar" data-bind="slideVisible: isEditing">
  72. <div style="float: left">
  73. <div class="toolbar-label">${_('LAYOUT')}</div>
  74. <a href="javascript: oneThirdLeftLayout()" onmouseover="viewModel.previewColumns('oneThirdLeft')" onmouseout="viewModel.previewColumns('')">
  75. <div class="layout-container">
  76. <div class="layout-box" style="width: 24px"></div>
  77. <div class="layout-box" style="width: 72px; margin-left: 4px"></div>
  78. </div>
  79. </a>
  80. <a href="javascript: fullLayout()" onmouseover="viewModel.previewColumns('full')" onmouseout="viewModel.previewColumns('')">
  81. <div class="layout-container">
  82. <div class="layout-box" style="width: 100px;"></div>
  83. </div>
  84. </a>
  85. <a data-bind="visible: columns().length == 0" href="javascript: magicLayout(viewModel)" onmouseover="viewModel.previewColumns('magic')" onmouseout="viewModel.previewColumns('')">
  86. <div class="layout-container">
  87. <div class="layout-box" style="width: 100px;"><i class="fa fa-magic"></i></div>
  88. </div>
  89. </a>
  90. </div>
  91. <div style="float: left; margin-left: 20px" data-bind="visible: columns().length > 0">
  92. <div class="toolbar-label">${_('WIDGETS')}</div>
  93. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableResultset() },
  94. draggable: {data: draggableResultset(), isEnabled: availableDraggableResultset,
  95. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  96. 'stop': function(event, ui){$('.card-body').slideDown('fast'); $root.collection.template.isGridLayout(true); }}}"
  97. title="${_('Grid Results')}" rel="tooltip" data-placement="top">
  98. <a data-bind="style: { cursor: $root.availableDraggableResultset() ? 'move' : 'default' }">
  99. <i class="fa fa-table"></i>
  100. </a>
  101. </div>
  102. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableResultset() },
  103. draggable: {data: draggableHtmlResultset(),
  104. isEnabled: availableDraggableResultset,
  105. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  106. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)}); $root.collection.template.isGridLayout(false); }}}"
  107. title="${_('HTML Results')}" rel="tooltip" data-placement="top">
  108. <a data-bind="style: { cursor: $root.availableDraggableResultset() ? 'move' : 'default' }">
  109. <i class="fa fa-code"></i>
  110. </a>
  111. </div>
  112. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableChart() },
  113. draggable: {data: draggableFacet(), isEnabled: availableDraggableChart,
  114. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  115. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
  116. title="${_('Text Facet')}" rel="tooltip" data-placement="top">
  117. <a data-bind="style: { cursor: $root.availableDraggableChart() ? 'move' : 'default' }">
  118. <i class="fa fa-sort-amount-asc"></i>
  119. </a>
  120. </div>
  121. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableChart() },
  122. draggable: {data: draggablePie(), isEnabled: availableDraggableChart,
  123. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  124. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
  125. title="${_('Pie Chart')}" rel="tooltip" data-placement="top">
  126. <a data-bind="style: { cursor: $root.availableDraggableChart() ? 'move' : 'default' }">
  127. <i class="hcha hcha-pie-chart"></i>
  128. </a>
  129. </div>
  130. <!-- <div class="draggable-widget" data-bind="draggable: {data: draggableHit(), options: {'start': function(event, ui){$('.card-body').slideUp('fast');}, 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}" title="${_('Hit Count')}" rel="tooltip" data-placement="top"><a data-bind="attr: {href: $root.availableDraggableResultset()}, css: {'btn-inverse': ! $root.availableDraggableResultset() }, style: { cursor: $root.availableDraggableResultset() ? 'move' : 'default' }"><i class="fa fa-tachometer"></i></a></div> -->
  131. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableChart() },
  132. draggable: {data: draggableBar(), isEnabled: availableDraggableChart,
  133. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  134. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
  135. title="${_('Bar Chart')}" rel="tooltip" data-placement="top">
  136. <a data-bind="style: { cursor: $root.availableDraggableChart() ? 'move' : 'default' }">
  137. <i class="hcha hcha-bar-chart"></i>
  138. </a>
  139. </div>
  140. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableNumbers() },
  141. draggable: {data: draggableLine(), isEnabled: availableDraggableNumbers,
  142. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  143. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
  144. title="${_('Line Chart')}" rel="tooltip" data-placement="top">
  145. <a data-bind="style: { cursor: $root.availableDraggableNumbers() ? 'move' : 'default' }">
  146. <i class="hcha hcha-line-chart"></i>
  147. </a>
  148. </div>
  149. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableHistogram() },
  150. draggable: {data: draggableHistogram(), isEnabled: availableDraggableHistogram,
  151. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  152. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
  153. title="${_('Timeline')}" rel="tooltip" data-placement="top">
  154. <a data-bind="style: { cursor: $root.availableDraggableHistogram() ? 'move' : 'default' }">
  155. <i class="hcha hcha-timeline-chart"></i>
  156. </a>
  157. </div>
  158. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableFilter() },
  159. draggable: {data: draggableFilter(), isEnabled: availableDraggableFilter,
  160. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  161. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
  162. title="${_('Filter Bar')}" rel="tooltip" data-placement="top">
  163. <a data-bind="style: { cursor: $root.availableDraggableFilter() ? 'move' : 'default' }">
  164. <i class="fa fa-filter"></i>
  165. </a>
  166. </div>
  167. <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableChart() },
  168. draggable: {data: draggableMap(), isEnabled: availableDraggableChart,
  169. options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
  170. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
  171. title="${_('Map')}" rel="tooltip" data-placement="top">
  172. <a data-bind="style: { cursor: $root.availableDraggableChart() ? 'move' : 'default' }">
  173. <i class="hcha hcha-map-chart"></i>
  174. </a>
  175. </div>
  176. </div>
  177. <div class="clearfix"></div>
  178. </div>
  179. <div id="emptyDashboard" data-bind="fadeVisible: !isEditing() && columns().length == 0">
  180. <div style="float:left; padding-top: 90px; margin-right: 20px; text-align: center; width: 260px">${ _('Click on the pencil to get started with your dashboard!') }</div>
  181. <img src="/search/static/art/hint_arrow.png" />
  182. </div>
  183. <div id="emptyDashboardEditing" data-bind="fadeVisible: isEditing() && columns().length == 0 && previewColumns() == ''">
  184. <div style="float:right; padding-top: 90px; margin-left: 20px; text-align: center; width: 260px">${ _('Click on a layout to start your dashboard!') }</div>
  185. <img src="/search/static/art/hint_arrow_horiz_flipped.png" />
  186. </div>
  187. <div data-bind="visible: isEditing() && previewColumns() != '' && columns().length == 0, css:{'with-top-margin': isEditing()}">
  188. <div class="container-fluid">
  189. <div class="row-fluid" data-bind="visible: previewColumns() == 'oneThirdLeft'">
  190. <div class="span3 preview-row"></div>
  191. <div class="span9 preview-row"></div>
  192. </div>
  193. <div class="row-fluid" data-bind="visible: previewColumns() == 'full'">
  194. <div class="span12 preview-row">
  195. </div>
  196. </div>
  197. <div class="row-fluid" data-bind="visible: previewColumns() == 'magic'">
  198. <div class="span12 preview-row">
  199. <div style="text-align: center; color:#EEE; font-size: 180px; margin-top: 80px">
  200. <i class="fa fa-magic"></i>
  201. </div>
  202. </div>
  203. </div>
  204. </div>
  205. </div>
  206. <div data-bind="css: {'dashboard': true, 'with-top-margin': isEditing()}">
  207. <div class="container-fluid">
  208. <div class="row-fluid" data-bind="template: { name: 'column-template', foreach: columns}">
  209. </div>
  210. <div class="clearfix"></div>
  211. </div>
  212. </div>
  213. <script type="text/html" id="column-template">
  214. <div data-bind="css: klass">
  215. <div class="container-fluid" data-bind="visible: $root.isEditing">
  216. <div data-bind="click: function(){$data.addEmptyRow(true)}, css: {'add-row': true, 'is-editing': $root.isEditing}, sortable: { data: drops, isEnabled: $root.isEditing, 'afterMove': function(event){var widget=event.item; var _r = $data.addEmptyRow(true); _r.addWidget(widget);$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)}); if ($root.collection.getFacetById(widget.id()) == null) { showAddFacetDemiModal(widget); } viewModel.search()}, options: {'placeholder': 'add-row-highlight', 'greedy': true, 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"></div>
  217. </div>
  218. <div data-bind="template: { name: 'row-template', foreach: rows}">
  219. </div>
  220. <div class="container-fluid" data-bind="visible: $root.isEditing">
  221. <div data-bind="click: function(){$data.addEmptyRow()}, css: {'add-row': true, 'is-editing': $root.isEditing}, sortable: { data: drops, isEnabled: $root.isEditing, 'afterMove': function(event){var widget=event.item; var _r = $data.addEmptyRow(); _r.addWidget(widget);$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)}); if ($root.collection.getFacetById(widget.id()) == null) { showAddFacetDemiModal(widget); } viewModel.search()}, options: {'placeholder': 'add-row-highlight', 'greedy': true, 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"></div>
  222. </div>
  223. </div>
  224. </script>
  225. <script type="text/html" id="row-template">
  226. <div class="emptyRow" data-bind="visible: widgets().length == 0 && $index() == 0 && $root.isEditing() && $parent.size() > 4 && $parent.rows().length == 1">
  227. <img src="/search/static/art/hint_arrow_flipped.png" style="float:left; margin-right: 10px"/>
  228. <div style="float:left; text-align: center; width: 260px">${_('Drag any of the widgets inside your empty row')}</div>
  229. <div class="clearfix"></div>
  230. </div>
  231. <div class="container-fluid">
  232. <div class="row-header" data-bind="visible: $root.isEditing">
  233. <span class="muted">${_('Row')}</span>
  234. <div style="display: inline; margin-left: 60px">
  235. <a href="javascript:void(0)" data-bind="visible: $index()<$parent.rows().length-1, click: function(){moveDown($parent, this)}"><i class="fa fa-chevron-down"></i></a>
  236. <a href="javascript:void(0)" data-bind="visible: $index()>0, click: function(){moveUp($parent, this)}"><i class="fa fa-chevron-up"></i></a>
  237. <a href="javascript:void(0)" data-bind="visible: $parent.rows().length > 1, click: function(){remove($parent, this)}"><i class="fa fa-times"></i></a>
  238. </div>
  239. </div>
  240. <div data-bind="css: {'row-fluid': true, 'row-container':true, 'is-editing': $root.isEditing},
  241. sortable: { template: 'widget-template', data: widgets, isEnabled: $root.isEditing,
  242. options: {'handle': '.move-widget', 'opacity': 0.7, 'placeholder': 'row-highlight', 'greedy': true,
  243. 'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});},
  244. 'helper': function(event){lastWindowScrollPosition = $(window).scrollTop(); $('.card-body').slideUp('fast'); var _par = $('<div>');_par.addClass('card card-widget');var _title = $('<h2>');_title.addClass('card-heading simple');_title.text($(event.toElement).text());_title.appendTo(_par);_par.height(80);_par.width(180);return _par;}},
  245. dragged: function(widget){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});showAddFacetDemiModal(widget);viewModel.search()}}">
  246. </div>
  247. </div>
  248. </script>
  249. <script type="text/html" id="widget-template">
  250. <div data-bind="attr: {'id': 'wdg_'+ id(),}, css: klass">
  251. <h2 class="card-heading simple">
  252. <span data-bind="visible: $root.isEditing">
  253. <a href="javascript:void(0)" class="move-widget"><i class="fa fa-arrows"></i></a>
  254. <a href="javascript:void(0)" data-bind="click: compress, visible: size() > 1"><i class="fa fa-step-backward"></i></a>
  255. <a href="javascript:void(0)" data-bind="click: expand, visible: size() < 12"><i class="fa fa-step-forward"></i></a>
  256. &nbsp;
  257. </span>
  258. <span data-bind="with: $root.collection.getFacetById(id())">
  259. <span data-bind="editable: label, editableOptions: {enabled: $root.isEditing()}"></span>
  260. </span>
  261. <!-- ko ifnot: $root.collection.getFacetById(id()) -->
  262. <span data-bind="editable: name, editableOptions: {enabled: $root.isEditing()}"></span>
  263. <!-- /ko -->
  264. <div class="inline pull-right" data-bind="visible: $root.isEditing">
  265. <a href="javascript:void(0)" data-bind="click: function(){remove($parent, this)}"><i class="fa fa-times"></i></a>
  266. </div>
  267. </h2>
  268. <div class="card-body" style="padding: 5px;">
  269. <div data-bind="template: { name: function() { return widgetType(); } }" class="widget-main-section"></div>
  270. </div>
  271. </div>
  272. </script>
  273. <script type="text/html" id="empty-widget">
  274. ${ _('This is an empty widget.')}
  275. </script>
  276. <script type="text/html" id="hit-widget">
  277. <!-- ko ifnot: $root.getFacetFromQuery(id()) -->
  278. <!-- /ko -->
  279. <!-- ko if: $root.getFacetFromQuery(id()) -->
  280. <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
  281. <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
  282. ${ _('Label') }: <input type="text" data-bind="value: label" />
  283. </div>
  284. <span data-bind="text: query" />: <span data-bind="text: count" />
  285. </div>
  286. <!-- /ko -->
  287. </script>
  288. <script type="text/html" id="facet-toggle">
  289. <!-- ko if: type() == 'range' -->
  290. ${ _('Start') }:
  291. <input type="text" class="input-large" data-bind="value: properties.start" />
  292. <br/>
  293. ${ _('End') }: <input type="text" class="input-large" data-bind="value: properties.end" />
  294. <br/>
  295. ${ _('Gap') }: <input type="text" class="input-small" data-bind="value: properties.gap" />
  296. <br/>
  297. ${ _('Min') }:
  298. <input type="text" class="input-medium" data-bind="value: properties.min" />
  299. <br/>
  300. ${ _('Max') }: <input type="text" class="input-medium" data-bind="value: properties.max" />
  301. <br/>
  302. <!-- /ko -->
  303. <!-- ko if: type() == 'field' -->
  304. ${ _('Limit') }: <input type="text" class="input-medium" data-bind="value: properties.limit" />
  305. <!-- /ko -->
  306. <a href="javascript: void(0)" class="btn btn-loading" data-bind="visible: properties.canRange, click: $root.collection.toggleRangeFacet" data-loading-text="...">
  307. <i class="fa" data-bind="css: { 'fa-arrows-h': type() == 'range', 'fa-circle': type() == 'field' }, attr: { title: type() == 'range' ? 'Range' : 'Term' }"></i>
  308. </a>
  309. <a href="javascript: void(0)" class="btn btn-loading" data-bind="click: $root.collection.toggleSortFacet" data-loading-text="...">
  310. <i class="fa" data-bind="css: { 'fa-caret-down': properties.sort() == 'desc', 'fa-caret-up': properties.sort() == 'asc' }"></i>
  311. </a>
  312. </script>
  313. <script type="text/html" id="facet-widget">
  314. <!-- ko ifnot: $root.getFacetFromQuery(id()) -->
  315. <!-- /ko -->
  316. <div class="widget-spinner" data-bind="visible: isLoading()">
  317. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  318. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  319. </div>
  320. <!-- ko if: $root.getFacetFromQuery(id()) -->
  321. <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
  322. <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
  323. <span data-bind="template: { name: 'facet-toggle', afterRender: function(){ $root.getWidgetById($parent.id).isLoading(false); } }">
  324. </span>
  325. </div>
  326. <div data-bind="with: $root.collection.getFacetById($parent.id())">
  327. <!-- ko if: type() != 'range' -->
  328. <div data-bind="foreach: $parent.counts">
  329. <div>
  330. <a href="javascript: void(0)">
  331. <!-- ko if: $index() != $parent.properties.limit() -->
  332. <!-- ko if: ! $data.selected -->
  333. <span data-bind="text: $data.value, click: function(){ $root.query.toggleFacet({facet: $data, widget_id: $parent.id()}) }"></span>
  334. <span class="counter" data-bind="text: ' (' + $data.count + ')', click: function(){ $root.query.toggleFacet({facet: $data, widget_id: $parent.id()}) }"></span>
  335. <!-- /ko -->
  336. <!-- ko if: $data.selected -->
  337. <span data-bind="click: function(){ $root.query.toggleFacet({facet: $data, widget_id: $parent.id()}) }">
  338. <span data-bind="text: $data.value"></span>
  339. <i class="fa fa-times"></i>
  340. </span>
  341. <!-- /ko -->
  342. <!-- /ko -->
  343. <!-- ko if: $index() == $parent.properties.limit() -->
  344. <!-- ko if: $parent.properties.prevLimit == undefined || $parent.properties.prevLimit == $parent.properties.limit() -->
  345. <span data-bind="click: function(){ $root.collection.upDownFacetLimit($parent.id(), 'up') }">
  346. ${ _('Show more...') }
  347. </span>
  348. <!-- /ko -->
  349. <!-- ko if: $parent.properties.prevLimit != undefined && $parent.properties.prevLimit != $parent.properties.limit() -->
  350. <span data-bind="click: function(){ $root.collection.upDownFacetLimit($parent.id(), 'up') }">
  351. ${ _('Show more') }
  352. </span>
  353. /
  354. <span data-bind="click: function(){ $root.collection.upDownFacetLimit($parent.id(), 'down') }">
  355. ${ _('less...') }
  356. </span>
  357. </span>
  358. <!-- /ko -->
  359. <!-- /ko -->
  360. </a>
  361. </div>
  362. </div>
  363. <!-- /ko -->
  364. <!-- ko if: type() == 'range' -->
  365. <div data-bind="foreach: $parent.counts">
  366. <div>
  367. <a href="javascript: void(0)">
  368. <!-- ko if: ! selected -->
  369. <span data-bind="click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field}) }">
  370. <span data-bind="text: $data.from + ' - ' + $data.to"></span>
  371. <span class="counter" data-bind="text: ' (' + $data.value + ')'"></span>
  372. </span>
  373. <!-- /ko -->
  374. <!-- ko if: selected -->
  375. <span data-bind="click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field}) }">
  376. <span data-bind="text: $data.from + ' - ' + $data.to"></span>
  377. <i class="fa fa-times"></i>
  378. </span>
  379. <!-- /ko -->
  380. </a>
  381. </div>
  382. </div>
  383. <!-- /ko -->
  384. </div>
  385. </div>
  386. <!-- /ko -->
  387. </script>
  388. <script type="text/html" id="resultset-widget">
  389. <!-- ko if: $root.collection.template.isGridLayout() -->
  390. <div style="float:left; margin-right: 10px" >
  391. <div data-bind="visible: ! $root.collection.template.showFieldList()" style="padding-top: 5px; display: inline-block">
  392. <a href="javascript: void(0)" data-bind="click: function(){ $root.collection.template.showFieldList(true) }">
  393. <i class="fa fa-chevron-right"></i>
  394. </a>
  395. </div>
  396. </div>
  397. <div data-bind="visible: $root.collection.template.showFieldList()" style="float:left; margin-right: 10px; background-color: #F6F6F6; padding: 5px">
  398. <span data-bind="visible: $root.collection.template.showFieldList()">
  399. <div>
  400. <a href="javascript: void(0)" class="pull-right" data-bind="click: function(){ $root.collection.template.showFieldList(false) }">
  401. <i class="fa fa-chevron-left"></i>
  402. </a>
  403. <input type="text" data-bind="value: $root.collection.template.fieldsAttributesFilter, valueUpdate:'afterkeydown'" placeholder="${_('Filter fields')}" style="width: 70%; margin-bottom: 10px" />
  404. </div>
  405. <div style="border-bottom: 1px solid #CCC; padding-bottom: 4px">
  406. <a href="javascript: void(0)" class="btn btn-mini"
  407. data-bind="click: toggleGridFieldsSelection, css: { 'btn-inverse': $root.collection.template.fields().length > 0 }"
  408. style="margin-right: 2px;">
  409. <i class="fa fa-square-o"></i>
  410. </a>
  411. <strong>${_('Field Name')}</strong>
  412. </div>
  413. <div class="fields-list" data-bind="foreach: $root.collection.template.filteredAttributeFields" style="max-height: 230px; overflow-y: auto; padding-left: 4px">
  414. <label class="checkbox">
  415. <input type="checkbox" data-bind="checkedValue: name, checked: $root.collection.template.fieldsSelected" />
  416. <span data-bind="text: name"></span>
  417. </label>
  418. </div>
  419. </span>
  420. </div>
  421. <div>
  422. <div data-bind="visible: !$root.isRetrievingResults() && $root.results().length == 0">
  423. ${ _('Your search did not match any documents.') }
  424. </div>
  425. <!-- ko if: $root.response().response -->
  426. <div data-bind="template: {name: 'resultset-pagination', data: $root.response() }"></div>
  427. <!-- /ko -->
  428. <div style="overflow-x: auto">
  429. <table id="result-container" data-bind="visible: !$root.isRetrievingResults()" style="margin-top: 0; width: 100%">
  430. <thead>
  431. <tr data-bind="visible: $root.results().length > 0">
  432. <th style="width: 18px">&nbsp;</th>
  433. <!-- ko foreach: $root.collection.template.fieldsSelected -->
  434. <th data-bind="with: $root.collection.getTemplateField($data), event: { mouseover: $root.enableGridlayoutResultChevron, mouseout: $root.disableGridlayoutResultChevron }" style="white-space: nowrap">
  435. <div style="display: inline-block; width:20px;">
  436. <a href="javascript: void(0)" data-bind="click: function(){ $root.collection.translateSelectedField($index(), 'left'); }">
  437. <i class="fa fa-chevron-left" data-bind="visible: $root.toggledGridlayoutResultChevron() && $index() > 0"></i>
  438. <i class="fa fa-chevron-left" style="color: #FFF" data-bind="visible: !$root.toggledGridlayoutResultChevron() || $index() == 0"></i>
  439. </a>
  440. </div>
  441. <div style="display: inline-block;">
  442. <a href="javascript: void(0)" title="${ _('Click to sort') }">
  443. <span data-bind="text: name, click: $root.collection.toggleSortColumnGridLayout"></span>
  444. <i class="fa" data-bind="visible: sort.direction() != null, css: { 'fa-chevron-down': sort.direction() == 'desc', 'fa-chevron-up': sort.direction() == 'asc' }"></i>
  445. </a>
  446. </div>
  447. <div style="display: inline-block; width:20px;">
  448. <a href="javascript: void(0)" data-bind="click: function(){ $root.collection.translateSelectedField($index(), 'right'); }">
  449. <i class="fa fa-chevron-right" data-bind="visible: $root.toggledGridlayoutResultChevron() && $index() < $root.collection.template.fields().length - 1"></i>
  450. <i class="fa fa-chevron-up" style="color: #FFF" data-bind="visible: !$root.toggledGridlayoutResultChevron() || $index() == $root.collection.template.fields().length - 1,"></i>
  451. </a>
  452. </div>
  453. </th>
  454. <!-- /ko -->
  455. </tr>
  456. <tr data-bind="visible: $root.collection.template.fieldsSelected().length == 0">
  457. <th style="width: 18px">&nbsp;</th>
  458. <th>${ ('Document') }</th>
  459. </tr>
  460. </thead>
  461. <tbody data-bind="foreach: { data: $root.results, as: 'documents' }" class="result-tbody">
  462. <tr class="result-row" data-bind="attr: {'id': 'doc_' + $data['id']}">
  463. <td><a href="javascript:void(0)" data-bind="click: toggleDocDetails"><i class="fa fa-caret-right"></i></a></td>
  464. <!-- ko foreach: $data['row'] -->
  465. <td data-bind="html: $data"></td>
  466. <!-- /ko -->
  467. </tr>
  468. </tbody>
  469. </table>
  470. </div>
  471. <div class="widget-spinner" data-bind="visible: $root.isRetrievingResults()">
  472. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  473. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  474. </div>
  475. </div>
  476. <!-- /ko -->
  477. </script>
  478. <script type="text/html" id="html-resultset-widget">
  479. <!-- ko ifnot: $root.collection.template.isGridLayout() -->
  480. <div data-bind="visible: $root.isEditing" style="margin-bottom: 20px">
  481. <ul class="nav nav-pills">
  482. <li class="active"><a href="javascript: void(0)" class="widget-editor-pill">${_('Editor')}</a></li>
  483. <li><a href="javascript: void(0)" class="widget-html-pill">${_('HTML')}</a></li>
  484. <li><a href="javascript: void(0)" class="widget-css-pill">${_('CSS & JS')}</a></li>
  485. <li><a href="javascript: void(0)" class="widget-settings-pill">${_('Properties')}</a></li>
  486. </ul>
  487. </div>
  488. <!-- ko if: $root.isEditing() -->
  489. <div class="widget-section widget-editor-section">
  490. <div class="row-fluid">
  491. <div class="span9">
  492. <div data-bind="freshereditor: {data: $root.collection.template.template}"></div>
  493. </div>
  494. <div class="span3">
  495. <h5 class="editor-title">${_('Available Fields')}</h5>
  496. <select data-bind="options: $root.collection.fields, optionsText: 'name', value: $root.collection.template.selectedVisualField" class="input-large chosen-select"></select>
  497. <button title="${ _('Click on this button to add the field') }" class="btn plus-btn" data-bind="click: $root.collection.template.addFieldToVisual">
  498. <i class="fa fa-plus"></i>
  499. </button>
  500. <h5 class="editor-title" style="margin-top: 30px">${_('Available Functions')}</h2>
  501. <select id="visualFunctions" data-bind="value: $root.collection.template.selectedVisualFunction" class="input-large chosen-select">
  502. <option title="${ _('Formats date or timestamp in DD-MM-YYYY') }" value="{{#date}} {{/date}}">{{#date}}</option>
  503. <option title="${ _('Formats date or timestamp in HH:mm:ss') }" value="{{#time}} {{/time}}">{{#time}}</option>
  504. <option title="${ _('Formats date or timestamp in DD-MM-YYYY HH:mm:ss') }" value="{{#datetime}} {{/datetime}}">{{#datetime}}</option>
  505. <option title="${ _('Formats a date in the full format') }" value="{{#fulldate}} {{/fulldate}}">{{#fulldate}}</option>
  506. <option title="${ _('Formats a date as a Unix timestamp') }" value="{{#timestamp}} {{/timestamp}}">{{#timestamp}}</option>
  507. <option title="${ _('Formats a Unix timestamp as Ns, Nmin, Ndays... ago') }" value="{{#fromnow}} {{/fromnow}}">{{#fromnow}}</option>
  508. <option title="${ _('Downloads and embed the file in the browser') }" value="{{#embeddeddownload}} {{/embeddeddownload}}">{{#embeddeddownload}}</option>
  509. <option title="${ _('Downloads the linked file') }" value="{{#download}} {{/download}}">{{#download}}</option>
  510. <option title="${ _('Preview file in File Browser') }" value="{{#preview}} {{/preview}}">{{#preview}}</option>
  511. <option title="${ _('Truncate a value after 100 characters') }" value="{{#truncate100}} {{/truncate100}}">{{#truncate100}}</option>
  512. <option title="${ _('Truncate a value after 250 characters') }" value="{{#truncate250}} {{/truncate250}}">{{#truncate250}}</option>
  513. <option title="${ _('Truncate a value after 500 characters') }" value="{{#truncate500}} {{/truncate500}}">{{#truncate500}}</option>
  514. </select>
  515. <button title="${ _('Click on this button to add the function') }" class="btn plus-btn" data-bind="click: $root.collection.template.addFunctionToVisual">
  516. <i class="fa fa-plus"></i>
  517. </button>
  518. <p class="muted" style="margin-top: 10px"></p>
  519. </div>
  520. </div>
  521. </div>
  522. <div class="widget-section widget-html-section" style="display: none">
  523. <div class="row-fluid">
  524. <div class="span9">
  525. <textarea data-bind="codemirror: {data: $root.collection.template.template, lineNumbers: true, htmlMode: true, mode: 'text/html' }" data-template="true"></textarea>
  526. </div>
  527. <div class="span3">
  528. <h5 class="editor-title">${_('Available Fields')}</h2>
  529. <select data-bind="options: $root.collection.fields, optionsText: 'name', value: $root.collection.template.selectedSourceField" class="input-medium chosen-select"></select>
  530. <button title="${ _('Click on this button to add the field') }" class="btn plus-btn" data-bind="click: $root.collection.template.addFieldToSource">
  531. <i class="fa fa-plus"></i>
  532. </button>
  533. <h5 class="editor-title" style="margin-top: 30px">${_('Available Functions')}</h2>
  534. <select id="sourceFunctions" data-bind="value: $root.collection.template.selectedSourceFunction" class="input-medium chosen-select">
  535. <option title="${ _('Formats a date in the DD-MM-YYYY format') }" value="{{#date}} {{/date}}">{{#date}}</option>
  536. <option title="${ _('Formats a date in the HH:mm:ss format') }" value="{{#time}} {{/time}}">{{#time}}</option>
  537. <option title="${ _('Formats a date in the DD-MM-YYYY HH:mm:ss format') }" value="{{#datetime}} {{/datetime}}">{{#datetime}}</option>
  538. <option title="${ _('Formats a date in the full format') }" value="{{#fulldate}} {{/fulldate}}">{{#fulldate}}</option>
  539. <option title="${ _('Formats a date as a Unix timestamp') }" value="{{#timestamp}} {{/timestamp}}">{{#timestamp}}</option>
  540. <option title="${ _('Shows the relative time') }" value="{{#fromnow}} {{/fromnow}}">{{#fromnow}}</option>
  541. <option title="${ _('Downloads and embed the file in the browser') }" value="{{#embeddeddownload}} {{/embeddeddownload}}">{{#embeddeddownload}}</option>
  542. <option title="${ _('Downloads the linked file') }" value="{{#download}} {{/download}}">{{#download}}</option>
  543. <option title="${ _('Preview file in File Browser') }" value="{{#preview}} {{/preview}}">{{#preview}}</option>
  544. <option title="${ _('Truncate a value after 100 characters') }" value="{{#truncate100}} {{/truncate100}}">{{#truncate100}}</option>
  545. <option title="${ _('Truncate a value after 250 characters') }" value="{{#truncate250}} {{/truncate250}}">{{#truncate250}}</option>
  546. <option title="${ _('Truncate a value after 500 characters') }" value="{{#truncate500}} {{/truncate500}}">{{#truncate500}}</option>
  547. </select>
  548. <button title="${ _('Click on this button to add the function') }" class="btn plus-btn" data-bind="click: $root.collection.template.addFunctionToSource">
  549. <i class="fa fa-plus"></i>
  550. </button>
  551. <p class="muted" style="margin-top: 10px"></p>
  552. </div>
  553. </div>
  554. </div>
  555. <div class="widget-section widget-css-section" style="display: none">
  556. <textarea data-bind="codemirror: {data: $root.collection.template.extracode, lineNumbers: true, htmlMode: true, mode: 'text/html' }"></textarea>
  557. </div>
  558. <div class="widget-section widget-settings-section" style="display: none, min-height:200px">
  559. ${ _('Sorting') }
  560. <div data-bind="foreach: $root.collection.template.fieldsSelected">
  561. <span data-bind="text: $data"></span>
  562. </div>
  563. <br/>
  564. </div>
  565. <!-- /ko -->
  566. <div style="overflow-x: auto">
  567. <div data-bind="visible: $root.results().length == 0">
  568. ${ _('Your search did not match any documents.') }
  569. </div>
  570. <!-- ko if: $root.response().response -->
  571. <div data-bind="template: {name: 'resultset-pagination', data: $root.response() }"></div>
  572. <!-- /ko -->
  573. <div id="result-container" data-bind="foreach: $root.results">
  574. <div class="result-row" data-bind="html: $data"></div>
  575. </div>
  576. <div class="widget-spinner" data-bind="visible: $root.isRetrievingResults()">
  577. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  578. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  579. </div>
  580. </div>
  581. <!-- /ko -->
  582. </script>
  583. <script type="text/html" id="resultset-pagination">
  584. <div style="text-align: center; margin-top: 4px">
  585. <a href="javascript: void(0)" title="${ _('Previous') }">
  586. <span data-bind="text: name, click: $root.collection.toggleSortColumnGridLayout"></span>
  587. <i class="fa fa-arrow-left" data-bind="
  588. visible: $data.response.start * 1.0 >= $root.collection.template.rows() * 1.0,
  589. click: function() { $root.query.paginate('prev') }">
  590. </i></a>
  591. ${ _('Showing') }
  592. <span data-bind="text: ($data.response.start + 1)"></span>
  593. ${ _('to') }
  594. <span data-bind="text: ($data.response.start + $root.collection.template.rows())"></span>
  595. ${ _('of') }
  596. <span data-bind="text: $data.response.numFound"></span>
  597. ${ _(' results') }
  598. <span data-bind="visible: $root.isEditing()">
  599. ${ _('Show') }
  600. <span class="spinedit-pagination">
  601. <input type="text" data-bind="spinedit: $root.collection.template.rows, valueUpdate:'afterkeydown'" style="text-align: center; margin-bottom: 0" />
  602. </span>
  603. ${ _('results per page') }
  604. </span>
  605. <a href="javascript: void(0)" title="${ _('Next') }">
  606. <span data-bind="text: name, click: $root.collection.toggleSortColumnGridLayout"></span>
  607. <i class="fa fa-arrow-right" data-bind="
  608. visible: ($root.collection.template.rows() * 1.0 + $data.response.start * 1.0) < $data.response.numFound,
  609. click: function() { $root.query.paginate('next') }">
  610. </i>
  611. </a>
  612. <!-- ko if: $data.response.numFound > 0 && $data.response.numFound <= 1000 -->
  613. <span class="pull-right">
  614. <form method="POST" action="${ url('search:download') }">
  615. <input type="hidden" name="collection" data-bind="value: ko.mapping.toJSON($root.collection)"/>
  616. <input type="hidden" name="query" data-bind="value: ko.mapping.toJSON($root.query)"/>
  617. <button class="btn" type="submit" name="json" title="${ _('Download as JSON') }"><i class="hfo hfo-file-json"></i></button>
  618. <button class="btn" type="submit" name="csv" title="${ _('Download as CSV') }"><i class="hfo hfo-file-csv"></i></button>
  619. <button class="btn" type="submit" name="xls" title="${ _('Download as Excel') }"><i class="hfo hfo-file-xls"></i></button>
  620. </form>
  621. </span>
  622. <!-- /ko -->
  623. </div>
  624. </script>
  625. <script type="text/html" id="histogram-widget">
  626. <!-- ko ifnot: $root.getFacetFromQuery(id()) -->
  627. <!-- /ko -->
  628. <div class="widget-spinner" data-bind="visible: isLoading()">
  629. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  630. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  631. </div>
  632. <!-- ko if: $root.getFacetFromQuery(id()) -->
  633. <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
  634. <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
  635. <span data-bind="template: { name: 'facet-toggle' }">
  636. </span>
  637. </div>
  638. <a href="javascript:void(0)" data-bind="click: $root.collection.timeLineZoom"><i class="fa fa-search-minus"></i></a>
  639. <span>
  640. ${ _('Group By') }
  641. <select class="input-medium" data-bind="options: $root.query.multiqs, optionsValue: 'id',optionsText: 'label', value: $root.query.selectedMultiq">
  642. </select>
  643. </span>
  644. <div data-bind="timelineChart: {datum: {counts: counts, extraSeries: extraSeries, widget_id: $parent.id(), label: label}, stacked: $root.collection.getFacetById($parent.id()).properties.stacked(), field: field, label: label, transformer: timelineChartDataTransformer,
  645. onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: $parent.id()}) },
  646. onStateChange: function(state){ $root.collection.getFacetById($parent.id()).properties.stacked(state.stacked); },
  647. onClick: function(d){ viewModel.query.selectRangeFacet({count: d.obj.value, widget_id: $parent.id(), from: d.obj.from, to: d.obj.to, cat: d.obj.field}) },
  648. onComplete: function(){ viewModel.getWidgetById(id).isLoading(false) }}" />
  649. </div>
  650. <!-- /ko -->
  651. </script>
  652. <script type="text/html" id="bar-widget">
  653. <!-- ko ifnot: $root.getFacetFromQuery(id()) -->
  654. <!-- /ko -->
  655. <div class="widget-spinner" data-bind="visible: isLoading()">
  656. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  657. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  658. </div>
  659. <!-- ko if: $root.getFacetFromQuery(id()) -->
  660. <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
  661. <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
  662. <span data-bind="template: { name: 'facet-toggle' }">
  663. </span>
  664. </div>
  665. <div data-bind="with: $root.collection.getFacetById($parent.id())">
  666. <!-- ko if: type() == 'range' -->
  667. <a href="javascript:void(0)" data-bind="click: $root.collection.timeLineZoom"><i class="fa fa-search-minus"></i></a>
  668. <!-- /ko -->
  669. </div>
  670. <div data-bind="barChart: {datum: {counts: counts, widget_id: $parent.id(), label: label}, stacked: false, field: field, label: label,
  671. transformer: barChartDataTransformer,
  672. onStateChange: function(state){ console.log(state); },
  673. onClick: function(d) {
  674. if (d.obj.field != undefined) {
  675. viewModel.query.selectRangeFacet({count: d.obj.value, widget_id: d.obj.widget_id, from: d.obj.from, to: d.obj.to, cat: d.obj.field});
  676. } else {
  677. viewModel.query.toggleFacet({facet: d.obj, widget_id: d.obj.widget_id});
  678. }
  679. },
  680. onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: d.obj.widget_id}) },
  681. onComplete: function(){ viewModel.getWidgetById(id).isLoading(false) } }"
  682. />
  683. </div>
  684. <!-- /ko -->
  685. </script>
  686. <script type="text/html" id="line-widget">
  687. <!-- ko ifnot: $root.getFacetFromQuery(id()) -->
  688. <!-- /ko -->
  689. <div class="widget-spinner" data-bind="visible: isLoading()">
  690. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  691. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  692. </div>
  693. <!-- ko if: $root.getFacetFromQuery(id()) -->
  694. <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
  695. <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
  696. <span data-bind="template: { name: 'facet-toggle' }">
  697. </span>
  698. </div>
  699. <a href="javascript:void(0)" data-bind="click: $root.collection.timeLineZoom"><i class="fa fa-search-minus"></i></a>
  700. <div data-bind="lineChart: {datum: {counts: counts, widget_id: $parent.id(), label: label}, field: field, label: label,
  701. transformer: lineChartDataTransformer,
  702. onClick: function(d){ viewModel.query.selectRangeFacet({count: d.obj.value, widget_id: d.obj.widget_id, from: d.obj.from, to: d.obj.to, cat: d.obj.field}) },
  703. onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: $parent.id()}) },
  704. onComplete: function(){ viewModel.getWidgetById(id).isLoading(false) } }"
  705. />
  706. </div>
  707. <!-- /ko -->
  708. </script>
  709. <script type="text/html" id="pie-widget">
  710. <!-- ko ifnot: $root.getFacetFromQuery(id()) -->
  711. <!-- /ko -->
  712. <!-- ko if: $root.getFacetFromQuery(id()) -->
  713. <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
  714. <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
  715. <span data-bind="template: { name: 'facet-toggle' }">
  716. </span>
  717. </div>
  718. <div data-bind="with: $root.collection.getFacetById($parent.id())">
  719. <!-- ko if: type() == 'range' -->
  720. <div data-bind="pieChart: {data: {counts: $parent.counts, widget_id: $parent.id}, field: field, fqs: $root.query.fqs,
  721. transformer: rangePieChartDataTransformer,
  722. maxWidth: 250,
  723. onClick: function(d){ viewModel.query.selectRangeFacet({count: d.data.obj.value, widget_id: d.data.obj.widget_id, from: d.data.obj.from, to: d.data.obj.to, cat: d.data.obj.field}) },
  724. onComplete: function(){ viewModel.getWidgetById($parent.id).isLoading(false)} }" />
  725. <!-- /ko -->
  726. <!-- ko if: type() != 'range' -->
  727. <div data-bind="pieChart: {data: {counts: $parent.counts, widget_id: $parent.id}, field: field, fqs: $root.query.fqs,
  728. transformer: pieChartDataTransformer,
  729. maxWidth: 250,
  730. onClick: function(d){viewModel.query.toggleFacet({facet: d.data.obj, widget_id: d.data.obj.widget_id})},
  731. onComplete: function(){viewModel.getWidgetById($parent.id).isLoading(false)}}" />
  732. <!-- /ko -->
  733. </div>
  734. </div>
  735. <!-- /ko -->
  736. <div class="widget-spinner" data-bind="visible: isLoading()">
  737. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  738. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  739. </div>
  740. </script>
  741. <script type="text/html" id="filter-widget">
  742. <div data-bind="visible: $root.query.fqs().length == 0" style="margin-top: 10px">${_('There are currently no filters applied.')}</div>
  743. <div data-bind="foreach: { data: $root.query.fqs, afterRender: function(){ isLoading(false); } }">
  744. <!-- ko if: $data.type() == 'field' -->
  745. <div class="filter-box">
  746. <a href="javascript:void(0)" class="pull-right" data-bind="click: function(){ viewModel.query.removeFilter($data); viewModel.search() }"><i class="fa fa-times"></i></a>
  747. <strong>${_('field')}</strong>:
  748. <span data-bind="text: $data.field"></span>
  749. <br/>
  750. <strong>${_('value')}</strong>:
  751. <span data-bind="text: $data.filter"></span>
  752. </div>
  753. <!-- /ko -->
  754. <!-- ko if: $data.type() == 'range' -->
  755. <div class="filter-box">
  756. <a href="javascript:void(0)" class="pull-right" data-bind="click: function(){ viewModel.query.removeFilter($data); viewModel.search() }"><i class="fa fa-times"></i></a>
  757. <strong>${_('field')}</strong>:
  758. <span data-bind="text: $data.field"></span>
  759. <br/>
  760. <span data-bind="foreach: $data.properties" style="font-weight: normal">
  761. <strong>${_('from')}</strong>: <span data-bind="text: $data.from"></span>
  762. <br/>
  763. <strong>${_('to')}</strong>: <span data-bind="text: $data.to"></span>
  764. </span>
  765. </div>
  766. <!-- /ko -->
  767. </div>
  768. <div class="clearfix"></div>
  769. <div class="widget-spinner" data-bind="visible: isLoading() && $root.query.fqs().length > 0">
  770. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  771. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  772. </div>
  773. </script>
  774. <script type="text/html" id="map-widget">
  775. <!-- ko ifnot: $root.getFacetFromQuery(id()) -->
  776. <!-- /ko -->
  777. <!-- ko if: $root.getFacetFromQuery(id()) -->
  778. <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
  779. <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
  780. ${ _('Scope') }:
  781. <select data-bind="selectedOptions: properties.scope" class="input-small">
  782. <option value="world">${ _("World") }</option>
  783. <option value="usa">${ _("USA") }</option>
  784. </select>
  785. <span data-bind="template: { name: 'facet-toggle' }">
  786. </span>
  787. </div>
  788. <div data-bind="with: $root.collection.getFacetById($parent.id())">
  789. <div data-bind="mapChart: {data: {counts: $parent.counts, scope: $root.collection.getFacetById($parent.id).properties.scope()},
  790. transformer: mapChartDataTransformer,
  791. maxWidth: 750,
  792. onClick: function(d){ viewModel.query.toggleFacet({facet: d, widget_id: $parent.id}) },
  793. onComplete: function(){ viewModel.getWidgetById($parent.id).isLoading(false)} }" />
  794. </div>
  795. </div>
  796. <!-- /ko -->
  797. <div class="widget-spinner" data-bind="visible: isLoading()">
  798. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  799. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  800. </div>
  801. </script>
  802. <div id="shareModal" class="modal hide" data-backdrop="true">
  803. <div class="modal-header">
  804. <a href="javascript: void(0)" data-dismiss="modal" class="pull-right"><i class="fa fa-times"></i></a>
  805. <h3>${_('Share this dashboard')}</h3>
  806. </div>
  807. <div class="modal-body">
  808. <p>${_('The following URL will show the current dashboard and the applied filters.')}</p>
  809. <input type="text" style="width: 540px" />
  810. </div>
  811. <div class="modal-footer">
  812. <a href="#" class="btn" data-dismiss="modal">${_('Close')}</a>
  813. </div>
  814. </div>
  815. <div id="addFacetDemiModal" class="demi-modal hide" data-backdrop="false">
  816. <div class="modal-body">
  817. <a href="javascript: void(0)" data-dismiss="modal" data-bind="click: addFacetDemiModalFieldCancel" class="pull-right"><i class="fa fa-times"></i></a>
  818. <div style="float: left; margin-right: 10px;text-align: center">
  819. <input id="addFacetInput" type="text" data-bind="value: $root.collection.template.fieldsModalFilter, valueUpdate:'afterkeydown'" placeholder="${_('Filter fields')}" class="input" style="float: left" /><br/>
  820. </div>
  821. <div>
  822. <ul data-bind="foreach: $root.collection.template.filteredModalFields().sort(function (l, r) { return l.name() > r.name() ? 1 : -1 }), visible: $root.collection.template.filteredModalFields().length > 0"
  823. class="unstyled inline fields-chooser" style="height: 100px; overflow-y: auto">
  824. <li data-bind="click: addFacetDemiModalFieldPreview">
  825. <span class="badge badge-info"><span data-bind="text: name(), attr: {'title': type()}"></span>
  826. </span>
  827. </li>
  828. </ul>
  829. <div class="alert alert-info inline" data-bind="visible: $root.collection.template.filteredModalFields().length == 0" style="margin-left: 124px;height: 42px;line-height: 42px">
  830. ${_('There are no fields matching your search term.')}
  831. </div>
  832. </div>
  833. </div>
  834. </div>
  835. <div id="settingsDemiModal" class="demi-modal hide" data-backdrop="false">
  836. <div class="modal-body">
  837. <a href="javascript: void(0)" data-dismiss="modal" class="pull-right"><i class="fa fa-times"></i></a>
  838. <div style="float: left; margin-right: 10px;text-align: center">
  839. <!-- ko if: $root.initial.inited() -->
  840. ${ _('Solr index') }
  841. <select data-bind="options: $root.initial.collections, value: $root.collection.name">
  842. </select>
  843. <!-- /ko -->
  844. </div>
  845. <div>
  846. ${ _('Visible to everybody') } <input type="checkbox" data-bind="checked: $root.collection.enabled"/>
  847. </div>
  848. </div>
  849. </div>
  850. <div id="genericLoader" style="display: none">
  851. <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
  852. <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
  853. </div>
  854. <script id="document-details" type="x-tmpl-mustache">
  855. <div class="document-details">
  856. <table>
  857. <tbody>
  858. {{#properties}}
  859. <tr>
  860. <th style="text-align: left; white-space: nobreak; vertical-align:top">{{key}}</th>
  861. <td width="100%">{{value}}</td>
  862. </tr>
  863. {{/properties}}
  864. </tbody>
  865. </table>
  866. </div>
  867. </script>
  868. ## Extra code for style and custom JS
  869. <span data-bind="html: $root.collection.template.extracode"></span>
  870. <link rel="stylesheet" href="/search/static/css/search.css">
  871. <link rel="stylesheet" href="/static/ext/css/hue-filetypes.css">
  872. <link rel="stylesheet" href="/static/ext/css/leaflet.css">
  873. <link rel="stylesheet" href="/static/ext/css/hue-charts.css">
  874. <link rel="stylesheet" href="/static/css/freshereditor.css">
  875. <link rel="stylesheet" href="/static/ext/css/codemirror.css">
  876. <link rel="stylesheet" href="/static/ext/css/bootstrap-editable.css">
  877. <link rel="stylesheet" href="/static/ext/css/bootstrap-slider.min.css">
  878. <link rel="stylesheet" href="/static/css/bootstrap-spinedit.css">
  879. <link rel="stylesheet" href="/static/ext/css/nv.d3.min.css">
  880. <link rel="stylesheet" href="/static/ext/chosen/chosen.min.css">
  881. <script src="/search/static/js/search.utils.js" type="text/javascript" charset="utf-8"></script>
  882. <script src="/search/static/js/lzstring.min.js" type="text/javascript" charset="utf-8"></script>
  883. <script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
  884. <script src="/static/ext/js/knockout.mapping-2.3.2.js" type="text/javascript" charset="utf-8"></script>
  885. <script src="/static/ext/js/knockout-sortable.min.js" type="text/javascript" charset="utf-8"></script>
  886. <script src="/static/ext/js/bootstrap-editable.min.js"></script>
  887. <script src="/static/ext/js/bootstrap-slider.min.js"></script>
  888. <script src="/static/js/bootstrap-spinedit.js"></script>
  889. <script src="/static/js/ko.editable.js"></script>
  890. <script src="/static/ext/js/shortcut.js" type="text/javascript" charset="utf-8"></script>
  891. <script src="/static/js/freshereditor.js" type="text/javascript" charset="utf-8"></script>
  892. <script src="/static/ext/js/codemirror-3.11.js"></script>
  893. <script src="/static/ext/js/moment.min.js" type="text/javascript" charset="utf-8"></script>
  894. <script src="/static/ext/js/codemirror-xml.js"></script>
  895. <script src="/static/ext/js/mustache.js"></script>
  896. <script src="/static/ext/js/jquery/plugins/jquery-ui-1.10.4.draggable-droppable-sortable.min.js" type="text/javascript" charset="utf-8"></script>
  897. <script src="/static/ext/js/jquery/plugins/jquery.flot.min.js" type="text/javascript" charset="utf-8"></script>
  898. <script src="/static/ext/js/jquery/plugins/jquery.flot.categories.min.js" type="text/javascript" charset="utf-8"></script>
  899. <script src="/static/ext/js/leaflet/leaflet.js" type="text/javascript" charset="utf-8"></script>
  900. <script src="/static/ext/chosen/chosen.jquery.min.js" type="text/javascript" charset="utf-8"></script>
  901. <script src="/search/static/js/search.ko.js" type="text/javascript" charset="utf-8"></script>
  902. <script src="/static/js/hue.geo.js"></script>
  903. <script src="/static/js/hue.colors.js"></script>
  904. <script src="/static/ext/js/d3.v3.js" type="text/javascript" charset="utf-8"></script>
  905. <script src="/static/ext/js/nv.d3.min.js" type="text/javascript" charset="utf-8"></script>
  906. <script src="/static/ext/js/topojson.v1.min.js" type="text/javascript" charset="utf-8"></script>
  907. <script src="/static/ext/js/topo/world.topo.js" type="text/javascript" charset="utf-8"></script>
  908. <script src="/static/ext/js/topo/usa.topo.js" type="text/javascript" charset="utf-8"></script>
  909. <script src="/search/static/js/nv.d3.datamaps.js" type="text/javascript" charset="utf-8"></script>
  910. <script src="/search/static/js/nv.d3.legend.js" type="text/javascript" charset="utf-8"></script>
  911. <script src="/search/static/js/nv.d3.multiBarWithBrushChart.js" type="text/javascript" charset="utf-8"></script>
  912. <script src="/search/static/js/nv.d3.lineWithBrushChart.js" type="text/javascript" charset="utf-8"></script>
  913. <script src="/search/static/js/nv.d3.growingDiscreteBar.js" type="text/javascript" charset="utf-8"></script>
  914. <script src="/search/static/js/nv.d3.growingDiscreteBarChart.js" type="text/javascript" charset="utf-8"></script>
  915. <script src="/search/static/js/nv.d3.growingMultiBar.js" type="text/javascript" charset="utf-8"></script>
  916. <script src="/search/static/js/nv.d3.growingMultiBarChart.js" type="text/javascript" charset="utf-8"></script>
  917. <script src="/search/static/js/nv.d3.growingPie.js" type="text/javascript" charset="utf-8"></script>
  918. <script src="/search/static/js/nv.d3.growingPieChart.js" type="text/javascript" charset="utf-8"></script>
  919. <script src="/search/static/js/charts.ko.js" type="text/javascript" charset="utf-8"></script>
  920. <script src="/static/ext/js/less-1.7.0.min.js" type="text/javascript" charset="utf-8"></script>
  921. <style type="text/css">
  922. .dashboard .container-fluid {
  923. padding: 6px;
  924. }
  925. .row-container {
  926. width: 100%;
  927. min-height: 70px;
  928. }
  929. .row-container.is-editing {
  930. border: 1px solid #e5e5e5;
  931. }
  932. .ui-sortable {
  933. background-color: #F3F3F3;
  934. min-height: 100px;
  935. }
  936. .ui-sortable h2 {
  937. padding-left: 10px!important;
  938. }
  939. .ui-sortable h2 ul {
  940. float: left;
  941. margin-right: 10px;
  942. font-size: 14px;
  943. }
  944. .ui-sortable-disabled {
  945. background-color: #FFF;
  946. }
  947. .card-column {
  948. border: none;
  949. min-height: 400px!important;
  950. }
  951. .card-widget {
  952. padding-top: 0;
  953. border: 0;
  954. min-height: 100px;
  955. }
  956. .card-widget .card-heading {
  957. font-size: 12px!important;
  958. font-weight: bold!important;
  959. line-height: 24px!important;
  960. }
  961. .card-widget .card-body {
  962. margin-top: 0;
  963. min-height: 40px;
  964. }
  965. .card-toolbar {
  966. margin: 0;
  967. padding: 4px;
  968. padding-top: 0;
  969. top: 70px;
  970. position: fixed;
  971. width: 100%;
  972. z-index: 1000;
  973. }
  974. .row-header {
  975. background-color: #F6F6F6;
  976. display: inline;
  977. padding: 3px;
  978. border: 1px solid #e5e5e5;
  979. border-bottom: none;
  980. }
  981. .row-highlight {
  982. background-color: #DDD;
  983. min-height: 100px;
  984. }
  985. #emptyDashboard {
  986. position: absolute;
  987. right: 204px;
  988. top: 80px;
  989. color: #666;
  990. font-size: 20px;
  991. z-index: 1000;
  992. }
  993. #emptyDashboardEditing {
  994. position: absolute;
  995. left: 120px;
  996. top: 160px;
  997. color: #666;
  998. font-size: 20px;
  999. }
  1000. .emptyRow {
  1001. margin-top: 10px;
  1002. margin-left: 140px;
  1003. color: #666;
  1004. font-size: 18px;
  1005. }
  1006. .preview-row {
  1007. background-color: #f9f9f9;
  1008. min-height: 400px!important;
  1009. margin-top: 30px;
  1010. }
  1011. .toolbar-label {
  1012. float: left;
  1013. font-weight: bold;
  1014. color: #999;
  1015. padding-left: 8px;
  1016. padding-top: 24px;
  1017. }
  1018. .draggable-widget {
  1019. width: 60px;
  1020. text-align: center;
  1021. float: left;
  1022. border: 1px solid #CCC;
  1023. margin-top: 10px;
  1024. margin-left: 10px;
  1025. cursor: move;
  1026. }
  1027. .draggable-widget.disabled {
  1028. cursor: default;
  1029. }
  1030. .draggable-widget a {
  1031. font-size: 28px;
  1032. line-height: 46px;
  1033. }
  1034. .draggable-widget.disabled a {
  1035. cursor: default;
  1036. color: #CCC;
  1037. }
  1038. .layout-container {
  1039. width: 100px;
  1040. float: left;
  1041. margin-top: 10px;
  1042. margin-left: 10px;
  1043. }
  1044. .layout-box {
  1045. float: left;
  1046. height: 48px;
  1047. background-color: #DDD;
  1048. text-align: center;
  1049. }
  1050. .layout-box i {
  1051. color: #333;
  1052. font-size: 28px;
  1053. line-height: 48px;
  1054. }
  1055. .layout-container:hover .layout-box {
  1056. background-color: #CCC;
  1057. }
  1058. .with-top-margin {
  1059. margin-top: 60px;
  1060. }
  1061. .ui-sortable .card-heading {
  1062. -webkit-touch-callout: none;
  1063. -webkit-user-select: none;
  1064. -khtml-user-select: none;
  1065. -moz-user-select: none;
  1066. -ms-user-select: none;
  1067. user-select: none;
  1068. }
  1069. .search-bar {
  1070. padding-top: 6px;
  1071. padding-bottom: 6px;
  1072. }
  1073. .widget-settings-section {
  1074. display: none;
  1075. }
  1076. em {
  1077. font-weight: bold;
  1078. background-color: yellow;
  1079. }
  1080. .nvd3 .nv-brush .extent {
  1081. fill-opacity: .225!important;
  1082. }
  1083. .nvd3 .nv-legend .disabled rect {
  1084. fill-opacity: 0;
  1085. }
  1086. .fields-chooser li {
  1087. cursor: pointer;
  1088. margin-bottom: 10px;
  1089. }
  1090. .fields-chooser li .badge {
  1091. font-weight: normal;
  1092. font-size: 12px;
  1093. }
  1094. .widget-spinner {
  1095. padding: 10px;
  1096. font-size: 80px;
  1097. color: #CCC;
  1098. text-align: center;
  1099. }
  1100. .card {
  1101. margin: 0;
  1102. }
  1103. .badge-left {
  1104. border-radius: 9px 0px 0px 9px;
  1105. padding-right: 5px;
  1106. }
  1107. .badge-right {
  1108. border-radius: 0px 9px 9px 0px;
  1109. padding-left: 5px;
  1110. }
  1111. .trash-filter {
  1112. cursor: pointer;
  1113. }
  1114. .move-widget {
  1115. cursor: move;
  1116. }
  1117. body.modal-open {
  1118. overflow: auto!important;
  1119. }
  1120. .editable-click {
  1121. cursor: pointer;
  1122. }
  1123. .CodeMirror {
  1124. border: 1px dotted #DDDDDD;
  1125. }
  1126. [contenteditable=true] {
  1127. border: 1px dotted #DDDDDD;
  1128. outline: 0;
  1129. margin-top: 20px;
  1130. margin-bottom: 20px;
  1131. min-height: 150px;
  1132. }
  1133. [contenteditable=true] [class*="span"], .tmpl [class*="span"] {
  1134. background-color: #eee;
  1135. -webkit-border-radius: 3px;
  1136. -moz-border-radius: 3px;
  1137. border-radius: 3px;
  1138. min-height: 40px;
  1139. line-height: 40px;
  1140. background-color: #F3F3F3;
  1141. border: 2px dashed #DDD;
  1142. }
  1143. .tmpl {
  1144. margin: 10px;
  1145. height: 60px;
  1146. }
  1147. .tmpl [class*="span"] {
  1148. color: #999;
  1149. font-size: 12px;
  1150. text-align: center;
  1151. font-weight: bold;
  1152. }
  1153. .editor-title {
  1154. font-weight: bold;
  1155. color: #262626;
  1156. border-bottom: 1px solid #338bb8;
  1157. }
  1158. .add-row {
  1159. background-color: #F6F6F6;
  1160. min-height: 36px;
  1161. border: 2px dashed #DDD;
  1162. text-align: center;
  1163. padding: 4px;
  1164. cursor: pointer;
  1165. }
  1166. .add-row:before {
  1167. color:#DDD;
  1168. display: inline-block;
  1169. font-family: FontAwesome;
  1170. font-style: normal;
  1171. font-weight: normal;
  1172. font-size: 24px;
  1173. line-height: 1;
  1174. -webkit-font-smoothing: antialiased;
  1175. -moz-osx-font-smoothing: grayscale;
  1176. content: "\f055";
  1177. }
  1178. .add-row-highlight {
  1179. min-height: 10px;
  1180. background-color:#CCC;
  1181. }
  1182. .document-details {
  1183. background-color: #F6F6F6;
  1184. padding: 10px;
  1185. border: 1px solid #e5e5e5;
  1186. }
  1187. .result-row:nth-child(even) {
  1188. background-color: #F6F6F6;
  1189. }
  1190. .demi-modal {
  1191. min-height: 80px;
  1192. }
  1193. .filter-box {
  1194. float: left;
  1195. margin-right: 10px;
  1196. margin-bottom: 10px;
  1197. background-color: #F6F6F6;
  1198. padding: 5px;
  1199. border:1px solid #d8d8d8;
  1200. -webkit-border-radius: 3px;
  1201. -moz-border-radius: 3px;
  1202. border-radius: 3px;
  1203. }
  1204. .spinedit-pagination div.spinedit .fa-chevron-up {
  1205. top: -7px;
  1206. }
  1207. .spinedit-pagination div.spinedit .fa-chevron-down {
  1208. top: 7px;
  1209. left: -4px;
  1210. }
  1211. .clearable {
  1212. background: url(/search/static/art/clearField.png) no-repeat right -10px center;
  1213. border: 1px solid #999;
  1214. padding: 3px 18px 3px 4px;
  1215. border-radius: 3px;
  1216. transition: background 0.4s !important;
  1217. }
  1218. @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  1219. .clearable {
  1220. background: url(/search/static/art/clearField@2x.png) no-repeat right -10px center;
  1221. background-size: 10px 10px;
  1222. }
  1223. }
  1224. .clearable.x {
  1225. background-position: right 5px center;
  1226. }
  1227. .clearable.onX {
  1228. cursor: pointer !important;
  1229. }
  1230. </style>
  1231. <script type="text/javascript" charset="utf-8">
  1232. var viewModel;
  1233. nv.dev = false;
  1234. var lastWindowScrollPosition = 0;
  1235. function pieChartDataTransformer(data) {
  1236. var _data = [];
  1237. $(data.counts).each(function (cnt, item) {
  1238. item.widget_id = data.widget_id;
  1239. _data.push({
  1240. label: item.value,
  1241. value: item.count,
  1242. obj: item
  1243. });
  1244. });
  1245. return _data;
  1246. }
  1247. function rangePieChartDataTransformer(data) {
  1248. var _data = [];
  1249. $(data.counts).each(function (cnt, item) {
  1250. item.widget_id = data.widget_id;
  1251. _data.push({
  1252. label: item.from + ' - ' + item.to,
  1253. from: item.from,
  1254. to: item.to,
  1255. value: item.value,
  1256. obj: item
  1257. });
  1258. });
  1259. return _data;
  1260. }
  1261. function barChartDataTransformer(rawDatum) {
  1262. var _datum = [];
  1263. var _data = [];
  1264. $(rawDatum.counts).each(function (cnt, item) {
  1265. item.widget_id = rawDatum.widget_id;
  1266. if (typeof item.from != "undefined") {
  1267. _data.push({
  1268. series: 0,
  1269. x: item.from,
  1270. x_end: item.to,
  1271. y: item.value,
  1272. obj: item
  1273. });
  1274. }
  1275. else {
  1276. _data.push({
  1277. series: 0,
  1278. x: item.value,
  1279. y: item.count,
  1280. obj: item
  1281. });
  1282. }
  1283. });
  1284. _datum.push({
  1285. key: rawDatum.label,
  1286. values: _data
  1287. });
  1288. return _datum;
  1289. }
  1290. function lineChartDataTransformer(rawDatum) {
  1291. var _datum = [];
  1292. var _data = [];
  1293. $(rawDatum.counts).each(function (cnt, item) {
  1294. item.widget_id = rawDatum.widget_id;
  1295. if (typeof item.from != "undefined") {
  1296. _data.push({
  1297. series: 0,
  1298. x: item.from,
  1299. x_end: item.to,
  1300. y: item.value,
  1301. obj: item
  1302. });
  1303. }
  1304. else {
  1305. _data.push({
  1306. series: 0,
  1307. x: item.value,
  1308. y: item.count,
  1309. obj: item
  1310. });
  1311. }
  1312. });
  1313. _datum.push({
  1314. key: rawDatum.label,
  1315. values: _data
  1316. });
  1317. return _datum;
  1318. }
  1319. function timelineChartDataTransformer(rawDatum) {
  1320. var _datum = [];
  1321. var _data = [];
  1322. $(rawDatum.counts).each(function (cnt, item) {
  1323. _data.push({
  1324. series: 0,
  1325. x: new Date(moment(item.from).valueOf()),
  1326. y: item.value,
  1327. obj: item
  1328. });
  1329. });
  1330. _datum.push({
  1331. key: rawDatum.label,
  1332. values: _data
  1333. });
  1334. // If multi query
  1335. $(rawDatum.extraSeries).each(function (cnt, item) {
  1336. if (cnt == 0) {
  1337. _datum = [];
  1338. }
  1339. var _data = [];
  1340. $(item.counts).each(function (cnt, item) {
  1341. _data.push({
  1342. series: cnt + 1,
  1343. x: new Date(moment(item.from).valueOf()),
  1344. y: item.value,
  1345. obj: item
  1346. });
  1347. });
  1348. _datum.push({
  1349. key: item.label,
  1350. values: _data
  1351. });
  1352. });
  1353. return _datum;
  1354. }
  1355. function mapChartDataTransformer(data) {
  1356. var _data = [];
  1357. $(data.counts).each(function (cnt, item) {
  1358. _data.push({
  1359. label: item.value,
  1360. value: item.count,
  1361. obj: item
  1362. });
  1363. });
  1364. return _data;
  1365. }
  1366. function toggleDocDetails(doc){
  1367. var _docRow = $("#doc_" + doc[viewModel.collection.idField()]);
  1368. if (_docRow.data("expanded") != null && _docRow.data("expanded")){
  1369. $("#doc_" + doc[viewModel.collection.idField()] + "_details").parent().hide();
  1370. _docRow.find(".fa-caret-down").removeClass("fa-caret-down").addClass("fa-caret-right");
  1371. _docRow.data("expanded", false);
  1372. }
  1373. else {
  1374. _docRow.data("expanded", true);
  1375. var _detailsRow = $("#doc_" + doc[viewModel.collection.idField()] + "_details");
  1376. if (_detailsRow.length > 0){
  1377. _detailsRow.parent().show();
  1378. }
  1379. else {
  1380. var _newRow = $("<tr>");
  1381. var _newCell = $("<td>").attr("colspan", _docRow.find("td").length).attr("id", "doc_" + doc[viewModel.collection.idField()] + "_details").html($("#genericLoader").html());
  1382. _newCell.appendTo(_newRow);
  1383. _newRow.insertAfter(_docRow);
  1384. viewModel.getDocument(doc);
  1385. }
  1386. _docRow.find(".fa-caret-right").removeClass("fa-caret-right").addClass("fa-caret-down");
  1387. }
  1388. }
  1389. function resizeFieldsList() {
  1390. $(".fields-list").css("max-height", Math.max($("#result-container").height(), 230));
  1391. }
  1392. $(document).ready(function () {
  1393. var _resizeTimeout = -1;
  1394. $(window).resize(function(){
  1395. window.clearTimeout(_resizeTimeout);
  1396. window.setTimeout(function(){
  1397. resizeFieldsList();
  1398. }, 200);
  1399. });
  1400. $(document).on("showDoc", function(e, doc){
  1401. viewModel.collection.selectedDocument(doc);
  1402. var _docDetailsRow = $("#doc_" + doc[viewModel.collection.idField()] + "_details");
  1403. var _doc = {
  1404. properties: []
  1405. };
  1406. for (var i=0; i< Object.keys(doc).length; i++){
  1407. _doc.properties.push({
  1408. key: Object.keys(doc)[i],
  1409. value: doc[Object.keys(doc)[i]]
  1410. });
  1411. }
  1412. var template = $("#document-details").html();
  1413. Mustache.parse(template);
  1414. var rendered = Mustache.render(template, _doc);
  1415. _docDetailsRow.html(rendered);
  1416. });
  1417. $(document).on("click", ".widget-settings-pill", function(){
  1418. $(this).parents(".card-body").find(".widget-section").hide();
  1419. $(this).parents(".card-body").find(".widget-settings-section").show();
  1420. $(this).parent().siblings().removeClass("active");
  1421. $(this).parent().addClass("active");
  1422. });
  1423. $(document).on("click", ".widget-editor-pill", function(){
  1424. $(this).parents(".card-body").find(".widget-section").hide();
  1425. $(this).parents(".card-body").find(".widget-editor-section").show();
  1426. $(this).parent().siblings().removeClass("active");
  1427. $(this).parent().addClass("active");
  1428. });
  1429. $(document).on("click", ".widget-html-pill", function(){
  1430. $(this).parents(".card-body").find(".widget-section").hide();
  1431. $(this).parents(".card-body").find(".widget-html-section").show();
  1432. $(document).trigger("refreshCodemirror");
  1433. $(this).parent().siblings().removeClass("active");
  1434. $(this).parent().addClass("active");
  1435. });
  1436. $(document).on("click", ".widget-css-pill", function(){
  1437. $(this).parents(".card-body").find(".widget-section").hide();
  1438. $(this).parents(".card-body").find(".widget-css-section").show();
  1439. $(document).trigger("refreshCodemirror");
  1440. $(this).parent().siblings().removeClass("active");
  1441. $(this).parent().addClass("active");
  1442. });
  1443. ko.bindingHandlers.slideVisible = {
  1444. init: function (element, valueAccessor) {
  1445. var value = valueAccessor();
  1446. $(element).toggle(ko.unwrap(value));
  1447. },
  1448. update: function (element, valueAccessor) {
  1449. var value = valueAccessor();
  1450. ko.unwrap(value) ? $(element).slideDown(100) : $(element).slideUp(100);
  1451. }
  1452. };
  1453. ko.bindingHandlers.fadeVisible = {
  1454. init: function(element, valueAccessor) {
  1455. var value = valueAccessor();
  1456. $(element).toggle(ko.unwrap(value));
  1457. },
  1458. update: function(element, valueAccessor) {
  1459. var value = valueAccessor();
  1460. $(element).stop();
  1461. ko.unwrap(value) ? $(element).fadeIn() : $(element).hide();
  1462. }
  1463. };
  1464. ko.extenders.numeric = function (target, precision) {
  1465. var result = ko.computed({
  1466. read: target,
  1467. write: function (newValue) {
  1468. var current = target(),
  1469. roundingMultiplier = Math.pow(10, precision),
  1470. newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
  1471. valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
  1472. if (valueToWrite !== current) {
  1473. target(valueToWrite);
  1474. } else {
  1475. if (newValue !== current) {
  1476. target.notifySubscribers(valueToWrite);
  1477. }
  1478. }
  1479. }
  1480. }).extend({ notify: 'always' });
  1481. result(target());
  1482. return result;
  1483. };
  1484. ko.bindingHandlers.freshereditor = {
  1485. init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
  1486. var _el = $(element);
  1487. var options = $.extend(valueAccessor(), {});
  1488. _el.html(options.data());
  1489. _el.freshereditor({
  1490. excludes: ['strikethrough', 'removeFormat', 'insertorderedlist', 'justifyfull', 'insertheading1', 'insertheading2', 'superscript', 'subscript']
  1491. });
  1492. _el.freshereditor("edit", true);
  1493. _el.on("mouseup", function () {
  1494. storeSelection();
  1495. updateValues();
  1496. });
  1497. var sourceDelay = -1;
  1498. _el.on("keyup", function () {
  1499. clearTimeout(sourceDelay);
  1500. storeSelection();
  1501. sourceDelay = setTimeout(function () {
  1502. updateValues();
  1503. }, 100);
  1504. });
  1505. $(".chosen-select").chosen({
  1506. disable_search_threshold: 10,
  1507. width: "75%"
  1508. });
  1509. $(document).on("addFieldToVisual", function(e, field){
  1510. _el.focus();
  1511. pasteHtmlAtCaret("{{" + field.name() + "}}");
  1512. });
  1513. $(document).on("addFunctionToVisual", function(e, fn){
  1514. _el.focus();
  1515. pasteHtmlAtCaret(fn);
  1516. });
  1517. function updateValues(){
  1518. $("[data-template]")[0].editor.setValue(stripHtmlFromFunctions(_el.html()));
  1519. valueAccessor().data(_el.html());
  1520. }
  1521. function storeSelection() {
  1522. if (window.getSelection) {
  1523. // IE9 and non-IE
  1524. sel = window.getSelection();
  1525. if (sel.getRangeAt && sel.rangeCount) {
  1526. range = sel.getRangeAt(0);
  1527. _el.data("range", range);
  1528. }
  1529. }
  1530. else if (document.selection && document.selection.type != "Control") {
  1531. // IE < 9
  1532. _el.data("selection", document.selection);
  1533. }
  1534. }
  1535. function pasteHtmlAtCaret(html) {
  1536. var sel, range;
  1537. if (window.getSelection) {
  1538. // IE9 and non-IE
  1539. sel = window.getSelection();
  1540. if (sel.getRangeAt && sel.rangeCount) {
  1541. if (_el.data("range")) {
  1542. range = _el.data("range");
  1543. }
  1544. else {
  1545. range = sel.getRangeAt(0);
  1546. }
  1547. range.deleteContents();
  1548. // Range.createContextualFragment() would be useful here but is
  1549. // non-standard and not supported in all browsers (IE9, for one)
  1550. var el = document.createElement("div");
  1551. el.innerHTML = html;
  1552. var frag = document.createDocumentFragment(), node, lastNode;
  1553. while ((node = el.firstChild)) {
  1554. lastNode = frag.appendChild(node);
  1555. }
  1556. range.insertNode(frag);
  1557. // Preserve the selection
  1558. if (lastNode) {
  1559. range = range.cloneRange();
  1560. range.setStartAfter(lastNode);
  1561. range.collapse(true);
  1562. sel.removeAllRanges();
  1563. sel.addRange(range);
  1564. }
  1565. }
  1566. } else if (document.selection && document.selection.type != "Control") {
  1567. // IE < 9
  1568. if (_el.data("selection")) {
  1569. _el.data("selection").createRange().pasteHTML(html);
  1570. }
  1571. else {
  1572. document.selection.createRange().pasteHTML(html);
  1573. }
  1574. }
  1575. }
  1576. }
  1577. };
  1578. ko.bindingHandlers.slider = {
  1579. init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
  1580. var _el = $(element);
  1581. var _options = $.extend(valueAccessor(), {});
  1582. _el.slider({
  1583. min: _options.min ? _options.min : 1,
  1584. max: _options.max ? _options.max : 10,
  1585. step: _options.step ? _options.step : 1,
  1586. handle: _options.handle ? _options.handle : 'circle',
  1587. value: _options.data(),
  1588. tooltip: 'always'
  1589. });
  1590. _el.on("slide", function (e) {
  1591. _options.data(e.value);
  1592. });
  1593. },
  1594. update: function (element, valueAccessor, allBindingsAccessor) {
  1595. var _options = $.extend(valueAccessor(), {});
  1596. $(element).slider("setValue", _options.data());
  1597. }
  1598. }
  1599. ko.bindingHandlers.clearable = {
  1600. init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
  1601. var _el = $(element);
  1602. function tog(v) {
  1603. return v ? 'addClass' : 'removeClass';
  1604. }
  1605. _el.addClass("clearable");
  1606. _el.on("input",function () {
  1607. _el[tog(this.value)]("x");
  1608. valueAccessor()(_el.val());
  1609. }).on("mousemove", function (e) {
  1610. _el[tog(this.offsetWidth - 18 < e.clientX - this.getBoundingClientRect().left)]("onX");
  1611. }).on("click", function () {
  1612. _el.removeClass("x onX").val("");
  1613. valueAccessor()("");
  1614. });
  1615. },
  1616. update: function (element, valueAccessor, allBindingsAccessor) {
  1617. $(element).val(ko.unwrap(valueAccessor()));
  1618. }
  1619. }
  1620. ko.bindingHandlers.spinedit = {
  1621. init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
  1622. $(element).spinedit({
  1623. minimum: 0,
  1624. maximum: 10000,
  1625. step: 5,
  1626. value: ko.unwrap(valueAccessor()),
  1627. numberOfDecimals: 0
  1628. });
  1629. $(element).on("valueChanged", function (e) {
  1630. valueAccessor()(e.value);
  1631. });
  1632. },
  1633. update: function (element, valueAccessor, allBindingsAccessor) {
  1634. $(element).spinedit("setValue", ko.unwrap(valueAccessor()));
  1635. }
  1636. }
  1637. ko.bindingHandlers.codemirror = {
  1638. init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
  1639. var options = $.extend(valueAccessor(), {});
  1640. var editor = CodeMirror.fromTextArea(element, options);
  1641. element.editor = editor;
  1642. editor.setValue(options.data());
  1643. editor.refresh();
  1644. var wrapperElement = $(editor.getWrapperElement());
  1645. $(document).on("refreshCodemirror", function(){
  1646. editor.setSize("100%", 300);
  1647. editor.refresh();
  1648. });
  1649. $(document).on("addFieldToSource", function(e, field){
  1650. if ($(element).data("template")){
  1651. editor.replaceSelection("{{" + field.name() + "}}");
  1652. }
  1653. });
  1654. $(document).on("addFunctionToSource", function(e, fn){
  1655. if ($(element).data("template")){
  1656. editor.replaceSelection(fn);
  1657. }
  1658. });
  1659. $(".chosen-select").chosen({
  1660. disable_search_threshold: 10,
  1661. width: "75%"
  1662. });
  1663. $('.chosen-select').trigger('chosen:updated');
  1664. var sourceDelay = -1;
  1665. editor.on("change", function (cm) {
  1666. clearTimeout(sourceDelay);
  1667. var _cm = cm;
  1668. sourceDelay = setTimeout(function () {
  1669. var _enc = $("<span>").html(_cm.getValue());
  1670. if (_enc.find("style").length > 0){
  1671. var parser = new less.Parser();
  1672. $(_enc.find("style")).each(function(cnt, item){
  1673. var _less = "#result-container {" + $(item).text() + "}";
  1674. try {
  1675. parser.parse(_less, function (err, tree) {
  1676. $(item).text(tree.toCSS());
  1677. });
  1678. }
  1679. catch (e){}
  1680. });
  1681. valueAccessor().data(_enc.html());
  1682. }
  1683. else {
  1684. valueAccessor().data(_cm.getValue());
  1685. }
  1686. if ($(".widget-html-pill").parent().hasClass("active")){
  1687. $("[contenteditable=true]").html(stripHtmlFromFunctions(valueAccessor().data()));
  1688. }
  1689. }, 100);
  1690. });
  1691. ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
  1692. wrapperElement.remove();
  1693. });
  1694. },
  1695. update: function (element, valueAccessor, allBindingsAccessor) {
  1696. var editor = element.editor;
  1697. editor.refresh();
  1698. }
  1699. };
  1700. var _query = ${ query | n,unicode };
  1701. if (window.location.hash != ""){
  1702. if (window.location.hash.indexOf("collection") == -1){
  1703. try {
  1704. var _decompress = LZString.decompressFromBase64(window.location.hash.substr(1));
  1705. if (_decompress != null && $.trim(_decompress) != ""){
  1706. _query = ko.mapping.fromJSON(LZString.decompressFromBase64(window.location.hash.substr(1)));
  1707. }
  1708. }
  1709. catch (e){}
  1710. }
  1711. }
  1712. viewModel = new SearchViewModel(${ collection.get_c(user) | n,unicode }, _query, ${ initial | n,unicode });
  1713. ko.applyBindings(viewModel);
  1714. viewModel.init(function(data){
  1715. $(".chosen-select").trigger("chosen:updated");
  1716. });
  1717. viewModel.isRetrievingResults.subscribe(function(value){
  1718. if (!value){
  1719. resizeFieldsList();
  1720. }
  1721. });
  1722. $("#addFacetDemiModal").on("hidden", function () {
  1723. if (typeof selectedWidget.hasBeenSelected == "undefined"){
  1724. addFacetDemiModalFieldCancel();
  1725. }
  1726. });
  1727. });
  1728. function showShareModal() {
  1729. if (window.location.search.indexOf("collection") == -1 && window.location.hash.indexOf("collection") == -1) {
  1730. $(document).trigger("error", "${_('The current collection must be saved to be shared.')}");
  1731. }
  1732. else {
  1733. $("#shareModal input[type='text']").on("focus", function () {
  1734. this.select();
  1735. });
  1736. var _search = window.location.search;
  1737. var _pathname = window.location.pathname;
  1738. if (_pathname.indexOf("${ url('search:new_search') }") > -1) {
  1739. _pathname = "${ url('search:index') }";
  1740. }
  1741. if (_search == "" && window.location.hash.indexOf("collection") > -1) {
  1742. _search = "?" + window.location.hash.substr(1);
  1743. }
  1744. if (_search != "") {
  1745. $("#shareModal input[type='text']").val(window.location.origin + _pathname + _search + "#" + LZString.compressToBase64(ko.mapping.toJSON(viewModel.query))).focus();
  1746. $("#shareModal").modal("show");
  1747. }
  1748. else {
  1749. $(document).trigger("error", "${_('The current collection cannot be shared.')}");
  1750. }
  1751. }
  1752. }
  1753. function toggleGridFieldsSelection() {
  1754. if (viewModel.collection.template.fields().length > 0) {
  1755. viewModel.collection.template.fieldsSelected([])
  1756. }
  1757. else {
  1758. var _fields = [];
  1759. $.each(viewModel.collection.fields(), function (index, field) {
  1760. _fields.push(field.name());
  1761. });
  1762. viewModel.collection.template.fieldsSelected(_fields);
  1763. }
  1764. }
  1765. var selectedWidget = null;
  1766. function showAddFacetDemiModal(widget) {
  1767. if (["resultset-widget", "html-resultset-widget", "filter-widget"].indexOf(widget.widgetType()) == -1) {
  1768. viewModel.collection.template.fieldsModalFilter("");
  1769. viewModel.collection.template.fieldsModalType(widget.widgetType());
  1770. viewModel.collection.template.fieldsModalFilter.valueHasMutated();
  1771. $('#addFacetInput').typeahead({
  1772. 'source': viewModel.collection.template.availableWidgetFieldsNames(),
  1773. 'updater': function(item) {
  1774. addFacetDemiModalFieldPreview({'name': function(){return item}});
  1775. return item;
  1776. }
  1777. });
  1778. selectedWidget = widget;
  1779. $("#addFacetDemiModal").modal("show");
  1780. $("#addFacetDemiModal input[type='text']").focus();
  1781. }
  1782. }
  1783. function addFacetDemiModalFieldPreview(field) {
  1784. var _existingFacet = viewModel.collection.getFacetById(selectedWidget.id());
  1785. if (selectedWidget != null) {
  1786. selectedWidget.hasBeenSelected = true;
  1787. selectedWidget.isLoading(true);
  1788. viewModel.collection.addFacet({'name': field.name(), 'widget_id': selectedWidget.id(), 'widgetType': selectedWidget.widgetType()});
  1789. if (_existingFacet != null) {
  1790. _existingFacet.label(field.name());
  1791. _existingFacet.field(field.name());
  1792. }
  1793. $("#addFacetDemiModal").modal("hide");
  1794. }
  1795. }
  1796. function addFacetDemiModalFieldCancel() {
  1797. viewModel.removeWidget(selectedWidget);
  1798. }
  1799. </script>
  1800. ${ commonfooter(messages) | n,unicode }