editor_components2.mako 96 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678
  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 django.utils.translation import ugettext as _
  18. from webpack_loader.templatetags.webpack_loader import render_bundle
  19. from desktop import conf
  20. from desktop.auth.backend import is_admin
  21. from desktop.lib.i18n import smart_unicode
  22. from desktop.views import _ko, antixss
  23. from metadata.conf import has_optimizer, OPTIMIZER
  24. from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, ENABLE_BATCH_EXECUTE, ENABLE_EXTERNAL_STATEMENT, ENABLE_PRESENTATION
  25. %>
  26. <%def name="includes(is_embeddable=False, suffix='')">
  27. <link rel="stylesheet" href="${ static('dashboard/css/common_dashboard.css') }">
  28. % if not is_embeddable:
  29. <link rel="stylesheet" href="${ static('notebook/css/notebook-layout.css') }">
  30. % endif
  31. <link rel="stylesheet" href="${ static('notebook/css/notebook2.css') }">
  32. <link rel="stylesheet" href="${ static('desktop/ext/css/bootstrap-editable.css') }">
  33. <link rel="stylesheet" href="${ static('desktop/ext/css/medium-editor.min.css') }">
  34. <link rel="stylesheet" href="${ static('desktop/css/bootstrap-medium-editor.css') }">
  35. <link rel="stylesheet" href="${ static('desktop/ext/css/bootstrap-datepicker.min.css') }">
  36. % if not is_embeddable:
  37. <script src="${ static('desktop/js/share2.vm.js') }"></script>
  38. % endif
  39. % if ENABLE_QUERY_SCHEDULING.get():
  40. <script src="${ static('oozie/js/coordinator-editor.ko.js') }"></script>
  41. <script src="${ static('oozie/js/list-oozie-coordinator.ko.js') }"></script>
  42. % endif
  43. <script src="${ static('desktop/js/ko.common-dashboard.js') }" type="text/javascript" charset="utf-8"></script>
  44. %if ENABLE_QUERY_BUILDER.get():
  45. <!-- For query builder -->
  46. <link rel="stylesheet" href="${ static('desktop/ext/css/jquery.contextMenu.min.css') }">
  47. <script src="${ static('desktop/ext/js/jquery/plugins/jquery.contextMenu.min.js') }"></script>
  48. <script src="${ static('desktop/js/queryBuilder.js') }"></script>
  49. <script>
  50. // query-builder-menu is the class to use
  51. // Callback will run after each rule add, just focus to the queryBuilder tab
  52. QueryBuilder.bindMenu('.query-builder-menu', function () {
  53. $("a[href='#queryBuilderTab']").click();
  54. });
  55. function generateQuery() {
  56. var hiveQuery = QueryBuilder.buildHiveQuery();
  57. if (hiveQuery.status == "fail") {
  58. $("#invalidQueryBuilder${ suffix }").modal("show");
  59. } else {
  60. replaceAce(hiveQuery.query);
  61. }
  62. }
  63. window.setInterval(function(){
  64. if ($('#queryBuilder tbody').length > 0 && $('#queryBuilder tbody').find('tr').length > 0){
  65. $('.button-panel').show();
  66. $('#queryBuilder').show();
  67. $('#queryBuilderAlert').hide();
  68. } else {
  69. $('.button-panel').hide();
  70. $('#queryBuilder').hide();
  71. $('#queryBuilderAlert').show();
  72. }
  73. }, 500, 'editor' + (window.location.getParameter('type') ? '-' + window.location.getParameter('type') : ''));
  74. </script>
  75. <!-- End query builder imports -->
  76. % endif
  77. ${ render_bundle('vendors~notebook') | n,unicode }
  78. ${ render_bundle('notebook') | n,unicode }
  79. <!--[if IE 9]>
  80. <script src="${ static('desktop/ext/js/classList.min.js') }" type="text/javascript" charset="utf-8"></script>
  81. <![endif]-->
  82. <%namespace name="dashboard" file="/common_dashboard.mako" />
  83. <%namespace name="sqlSyntaxDropdown" file="/sql_syntax_dropdown.mako" />
  84. </%def>
  85. <%def name="topBar(suffix='')">
  86. <style type="text/css">
  87. % if conf.CUSTOM.BANNER_TOP_HTML.get():
  88. .search-bar {
  89. top: 58px!important;
  90. }
  91. .show-assist,
  92. .show-assist-right {
  93. top: 110px!important;
  94. }
  95. .main-content {
  96. top: 112px!important;
  97. }
  98. .context-panel {
  99. height: calc(100% - 104px);
  100. top: 104px;
  101. }
  102. % endif
  103. </style>
  104. ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
  105. <div class="navbar hue-title-bar" data-bind="visible: ! $root.isPresentationMode() && ! $root.isResultFullScreenMode()">
  106. <div class="navbar-inner">
  107. <div class="container-fluid">
  108. <!-- ko template: { name: 'notebook-menu-buttons-${ suffix }' } --><!-- /ko -->
  109. <div class="nav-collapse">
  110. <ul class="nav editor-nav">
  111. <li class="app-header" style="display:none" data-bind="visible: true">
  112. <!-- ko if: editorMode -->
  113. <a data-bind="hueLink: '${ url('notebook:editor') }?type=' + editorType(), attr: { 'title': editorTypeTitle() + '${ _(' Editor') }'}" style="cursor: pointer">
  114. <!-- ko template: { name: 'app-icon-template', data: { icon: editorType() } } --><!-- /ko -->
  115. <!-- ko switch: editorType() -->
  116. <!-- ko case: 'impala' -->Impala<!-- /ko -->
  117. <!-- ko case: 'rdbms' -->DB Query<!-- /ko -->
  118. <!-- ko case: 'pig' -->Pig<!-- /ko -->
  119. <!-- ko case: 'java' -->Java<!-- /ko -->
  120. <!-- ko case: 'spark2' -->Spark<!-- /ko -->
  121. <!-- ko case: 'sqoop1' -->Sqoop 1<!-- /ko -->
  122. <!-- ko case: 'distcp' -->DistCp<!-- /ko -->
  123. <!-- ko case: 'shell' -->Shell<!-- /ko -->
  124. <!-- ko case: 'mapreduce' -->MapReduce<!-- /ko -->
  125. <!-- ko case: ['beeswax', 'hive'] -->Hive<!-- /ko -->
  126. <!-- ko case: 'mapreduce' -->MapReduce<!-- /ko -->
  127. <!-- ko case: 'spark' -->Scala<!-- /ko -->
  128. <!-- ko case: 'pyspark' -->PySpark<!-- /ko -->
  129. <!-- ko case: 'r' -->R<!-- /ko -->
  130. <!-- ko case: 'jar' -->Spark Submit Jar<!-- /ko -->
  131. <!-- ko case: 'py' -->Spark Submit Python<!-- /ko -->
  132. <!-- ko case: 'solr' -->Solr SQL<!-- /ko -->
  133. <!-- ko case: 'kafkasql' -->Kafka SQL<!-- /ko -->
  134. <!-- ko case: 'markdown' -->Markdown<!-- /ko -->
  135. <!-- ko case: 'text' -->Text<!-- /ko -->
  136. <!-- ko case: 'clickhouse' -->ClickHouse<!-- /ko -->
  137. <!-- ko case: $default --><span data-bind="text: editorTypeTitle()"></span><!-- /ko -->
  138. <!-- /ko -->
  139. <!-- ko component: { name: 'hue-favorite-app', params: { app: 'editor', interpreter: editorType() }} --><!-- /ko -->
  140. </a>
  141. <!-- /ko -->
  142. <!-- ko ifnot: editorMode -->
  143. <i class="fa fa-file-text-o app-icon" style="vertical-align: middle"></i>
  144. Notebook
  145. <!-- ko component: { name: 'hue-favorite-app', params: { app: 'notebook' }} --><!-- /ko -->
  146. <!-- /ko -->
  147. </li>
  148. <!-- ko with: selectedNotebook -->
  149. <li class="no-horiz-padding">
  150. <a>&nbsp;</a>
  151. </li>
  152. <li data-bind="visible: isHistory" style="display: none" class="no-horiz-padding muted">
  153. <a title="${ _('This is a history query') }"><i class="fa fa-fw fa-history"></i></a>
  154. </li>
  155. <li data-bind="visible: directoryUuid" style="display: none" class="no-horiz-padding muted">
  156. <a title="${ _('Open directory of this query') }" data-bind="hueLink: '/home/?uuid=' + directoryUuid()"
  157. class="pointer inactive-action" href="javascript:void(0)"><i class="fa fa-fw fa-folder-o"></i>
  158. </a>
  159. </li>
  160. <li data-bind="visible: parentSavedQueryUuid" style="display: none" class="no-horiz-padding muted">
  161. <a title="${ _('Click to open original saved query') }" data-bind="click: function() { $root.openNotebook(parentSavedQueryUuid()) }" class="pointer inactive-action">
  162. <i class="fa fa-fw fa-file-o"></i>
  163. </a>
  164. </li>
  165. <li data-bind="visible: isSaved() && ! isHistory() && ! parentSavedQueryUuid()" style="display: none" class="no-horiz-padding muted">
  166. <a title="${ _('This is a saved query') }"><i class="fa fa-fw fa-file-o"></i></a>
  167. </li>
  168. <li data-bind="visible: isSchedulerJobRunning" style="display: none" class="no-horiz-padding muted">
  169. <a title="${ _('Click to open original saved query') }" data-bind="click: function() { $root.openNotebook(parentSavedQueryUuid()) }" class="pointer inactive-action">
  170. ${ _("Scheduling on") }
  171. </a>
  172. </li>
  173. <li class="query-name no-horiz-padding skip-width-calculation">
  174. <a href="javascript:void(0)">
  175. <div class="notebook-name-desc" data-bind="editable: name, editableOptions: { inputclass: 'notebook-name-input', enabled: true, placement: 'bottom', emptytext: '${_ko('Add a name...')}', tpl: '<input type=\'text\' maxlength=\'255\'>' }"></div>
  176. </a>
  177. </li>
  178. <li class="skip-width-calculation" data-bind="tooltip: { placement: 'bottom', title: description }">
  179. <a href="javascript:void(0)">
  180. <div class="notebook-name-desc" data-bind="editable: description, editableOptions: { type: 'textarea', enabled: true, placement: 'bottom', emptytext: '${_ko('Add a description...')}' }"></div>
  181. </a>
  182. </li>
  183. <!-- /ko -->
  184. </ul>
  185. </div>
  186. </div>
  187. </div>
  188. </div>
  189. <script type="text/html" id="notebook-menu-buttons-${ suffix }">
  190. <div class="pull-right margin-right-10">
  191. % if ENABLE_PRESENTATION.get():
  192. <!-- ko with: selectedNotebook() -->
  193. <div class="btn-group">
  194. <a class="btn" data-bind="click: function() { isPresentationMode(!isPresentationMode()); },
  195. css: {'btn-inverse': $root.isPresentationMode()}, attr: {title: isPresentationMode() ? '${ _ko('Exit presentation') }' : '${ _ko('View as a presentation') }'}">
  196. <i class="fa fa-line-chart"></i>
  197. </a>
  198. <!-- ko if: $root.canSave() -->
  199. <a class="btn dropdown-toggle" data-toggle="dropdown" href="javascript: void(0)"><span class="caret"></span></a>
  200. <ul class="dropdown-menu pull-right">
  201. <li>
  202. <a class="pointer" title="${ _ko('Whether to open in presentation or editor mode by default') }" data-bind="click: function() { isPresentationModeDefault(!isPresentationModeDefault()); }">
  203. <i class="fa" data-bind="css: {'fa-toggle-on': isPresentationModeDefault(), 'fa-toggle-off': !isPresentationModeDefault()}"></i> ${ _('Open as presentation') }
  204. </a>
  205. </li>
  206. </ul>
  207. <!-- /ko -->
  208. </div>
  209. <!-- /ko -->
  210. % endif
  211. <div class="btn-group">
  212. <a class="btn" rel="tooltip" data-placement="bottom" data-loading-text="${ _("Saving...") }" data-bind="click: function() { if ($root.canSave() ) { saveNotebook() } else { $('#saveAsModal${ suffix }').modal('show');} }, attr: { title: $root.canSave() ? '${ _ko('Save') }' : '${ _ko('Save As') }' }">
  213. <i class="fa fa-save"></i>
  214. </a>
  215. <!-- ko if: $root.canSave -->
  216. <a class="btn dropdown-toggle" data-toggle="dropdown" href="javascript: void(0)"><span class="caret"></span></a>
  217. <ul class="dropdown-menu pull-right">
  218. <li>
  219. <a class="pointer" data-bind="click: function() { $('#saveAsModal${ suffix }').modal('show'); }">
  220. <i class="fa fa-fw fa-save"></i> ${ _('Save as...') }
  221. </a>
  222. </li>
  223. </ul>
  224. <!-- /ko -->
  225. </div>
  226. <!-- ko template: { ifnot: editorMode() || isPresentationMode(), name: 'notebook-actions' }--><!-- /ko -->
  227. <!-- ko ifnot: isPresentationMode() -->
  228. <div class="dropdown pull-right margin-left-10">
  229. <a class="btn" data-toggle="dropdown" href="javascript: void(0)">
  230. <i class="fa fa-fw fa-ellipsis-v"></i>
  231. </a>
  232. <ul class="dropdown-menu pull-right">
  233. <li>
  234. <!-- ko if: editorMode -->
  235. <a href="javascript:void(0)" data-bind="click: function() { hueUtils.removeURLParameter('editor'); newNotebook($root.editorType(), null, selectedNotebook() ? $root.selectedNotebook().snippets()[0].currentQueryTab() : null); }, attr: { 'title': '${ _('New ') }' + editorTypeTitle() + '${ _(' Query') }' }">
  236. <i class="fa fa-fw fa-file-o"></i> ${ _('New') }
  237. </a>
  238. <!-- /ko -->
  239. <!-- ko ifnot: editorMode -->
  240. <a href="javascript:void(0)" data-bind="click: newNotebook">
  241. <i class="fa fa-fw fa-file-o"></i> ${ _('New Notebook') }
  242. </a>
  243. <!-- /ko -->
  244. </li>
  245. <li>
  246. <a href="javascript:void(0)" data-bind="publish: { 'assist.show.documents': editorMode() ? 'query-' + editorType() : editorType() }">
  247. <svg class="hi hi-fw hi-bigger"><use xlink:href="#hi-documents"></use></svg> <span data-bind="text: editorMode() ? '${ _ko('Queries') }' : '${ _ko('Notebooks') }'"></span>
  248. </a>
  249. </li>
  250. <li class="divider"></li>
  251. <!-- ko if: $root.canSave -->
  252. <li>
  253. <a href="javascript:void(0)" class="share-link" data-bind="click: prepareShareModal,
  254. css: {'isShared': isShared()}">
  255. <i class="fa fa-fw fa-users"></i> ${ _('Share') }
  256. </a>
  257. </li>
  258. <!-- /ko -->
  259. <li>
  260. <a href="javascript:void(0)" data-bind="click: showSessionPanel">
  261. <i class="fa fa-fw fa-cogs"></i> ${ _('Sessions') }
  262. </a>
  263. </li>
  264. </ul>
  265. </div>
  266. <!-- /ko -->
  267. </div>
  268. </script>
  269. <!-- ko if: $root.isResultFullScreenMode() -->
  270. <a class="hueAnchor collapse-results" href="javascript:void(0)" title="${ _('Collapse results') }" data-bind="click: function(){ $root.isResultFullScreenMode(false); }">
  271. <i class="fa fa-times fa-fw"></i>
  272. </a>
  273. <!-- /ko -->
  274. <!-- ko if: $root.isPresentationMode() -->
  275. <a class="hueAnchor collapse-results" href="javascript:void(0)" title="${ _('Exit presentation') }" data-bind="click: function(){ $root.selectedNotebook().isPresentationMode(false); }">
  276. <i class="fa fa-times fa-fw"></i>
  277. </a>
  278. <!-- /ko -->
  279. <div class="player-toolbar margin-top-10" data-bind="visible: $root.isPresentationMode()" style="display: none">
  280. <!-- ko if: $root.isPresentationMode() -->
  281. <!-- ko if: $root.selectedNotebook() -->
  282. <!-- ko if: $root.selectedNotebook().name() || $root.selectedNotebook().description() -->
  283. <h2 class="margin-left-30 margin-right-10 inline padding-left-5" data-bind="text: $root.selectedNotebook().name"></h2>
  284. <h2 class="muted inline" data-bind="text: $root.selectedNotebook().description"></h2>
  285. <div class="clearfix"></div>
  286. <!-- /ko -->
  287. <!-- ko template: { name: 'notebook-menu-buttons-${ suffix }' } --><!-- /ko -->
  288. <div class="margin-left-30 margin-top-10 padding-left-5 margin-bottom-20">
  289. <!-- ko template: { name: 'notebook-actions' } --><!-- /ko -->
  290. <!-- ko if: $root.preEditorTogglingSnippet -->
  291. <!-- ko template: { if: $root.isPresentationMode(), name: 'snippet-variables', data: $root.preEditorTogglingSnippet }--><!-- /ko -->
  292. <!-- /ko -->
  293. </div>
  294. <!-- /ko -->
  295. <!-- /ko -->
  296. </div>
  297. </%def>
  298. <%def name="commonHTML(is_embeddable=False, suffix='')">
  299. <div id="helpModal${ suffix }" class="modal transparent-modal hide" data-backdrop="true" style="width:980px;margin-left:-510px!important">
  300. <div class="modal-header">
  301. <button type="button" class="close" data-dismiss="modal" aria-label="${ _('Close') }"><span aria-hidden="true">&times;</span></button>
  302. <h2 class="modal-title">${_('Editor help')}</h2>
  303. </div>
  304. <div class="modal-body">
  305. <!-- ko component: 'aceKeyboardShortcuts' --><!-- /ko -->
  306. </div>
  307. <div class="modal-footer">
  308. <a href="javascript: void(0)" class="btn" data-dismiss="modal">${_('Close')}</a>
  309. </div>
  310. </div>
  311. <div id="combinedContentModal${ suffix }" class="modal hide" data-backdrop="true" style="width:780px;margin-left:-410px!important">
  312. <div class="modal-header">
  313. <button type="button" class="close" data-dismiss="modal" aria-label="${ _('Close') }"><span aria-hidden="true">&times;</span></button>
  314. <h2 class="modal-title">${_('All Notebook content')}</h2>
  315. </div>
  316. <div class="modal-body">
  317. <pre data-bind="oneClickSelect, text: combinedContent"></pre>
  318. </div>
  319. <div class="modal-footer">
  320. <a href="javascript: void(0)" class="btn" data-dismiss="modal">${_('Close')}</a>
  321. </div>
  322. </div>
  323. % if ENABLE_QUERY_BUILDER.get():
  324. <div id="invalidQueryBuilder${ suffix }" class="modal hide">
  325. <div class="modal-header">
  326. <button type="button" class="close" data-dismiss="modal" aria-label="${ _('Close') }"><span aria-hidden="true">&times;</span></button>
  327. <h2 class="modal-title">${_('Invalid Query')}</h2>
  328. </div>
  329. <div class="modal-body">
  330. <p>${_('Query requires a select or an aggregate.')}</p>
  331. </div>
  332. <div class="modal-footer">
  333. <a class="btn" data-dismiss="modal">${_('Close')}</a>
  334. </div>
  335. </div>
  336. % endif
  337. % if not is_embeddable:
  338. <a title="${_('Toggle Assist')}" class="pointer show-assist" data-bind="visible: !$root.isLeftPanelVisible() && $root.assistAvailable(), click: function() { $root.isLeftPanelVisible(true); huePubSub.publish('assist.set.manual.visibility'); }">
  339. <i class="fa fa-chevron-right"></i>
  340. </a>
  341. <a title="${_('Toggle Assist')}" class="pointer show-assist-right" data-bind="visible: !$root.isRightPanelVisible() && $root.isRightPanelAvailable(), click: function() { $root.isRightPanelVisible(true); huePubSub.publish('assist.set.manual.visibility'); }">
  342. <i class="fa fa-chevron-left"></i>
  343. </a>
  344. % endif
  345. <div data-bind="css: {'main-content': true, 'editor-mode': $root.editorMode()}">
  346. <div class="vertical-full tab-pane row-fluid panel-container" data-bind="css: { active: selectedNotebook() === $data }, template: { name: 'notebook${ suffix }'}">
  347. </div>
  348. </div>
  349. <script type="text/html" id="notebook${ suffix }">
  350. % if not is_embeddable:
  351. <div class="assist-container left-panel" data-bind="visible: isLeftPanelVisible() && assistAvailable()">
  352. <a title="${_('Toggle Assist')}" class="pointer hide-assist" data-bind="click: function() { isLeftPanelVisible(false); huePubSub.publish('assist.set.manual.visibility'); }">
  353. <i class="fa fa-chevron-left"></i>
  354. </a>
  355. <div class="assist" data-bind="component: {
  356. name: 'assist-panel',
  357. params: {
  358. user: user,
  359. sql: {
  360. sourceTypes: sqlSourceTypes,
  361. activeSourceType: activeSqlSourceType,
  362. navigationSettings: {
  363. openDatabase: false,
  364. openItem: false,
  365. showStats: true,
  366. pinEnabled: true
  367. },
  368. },
  369. visibleAssistPanels: editorMode() ? ['sql'] : []
  370. }
  371. }"></div>
  372. </div>
  373. <div class="resizer" data-bind="visible: isLeftPanelVisible() && assistAvailable(), splitDraggable : { appName: 'notebook', leftPanelVisible: isLeftPanelVisible, rightPanelVisible: isRightPanelVisible, rightPanelAvailable: isRightPanelAvailable, onPosition: function(){ huePubSub.publish('split.draggable.position') } }"><div class="resize-bar">&nbsp;</div></div>
  374. % endif
  375. <div class="content-panel" data-bind="event: { scroll: function(){ var ls = $(MAIN_SCROLLABLE).data('lastScroll'); if (ls && ls != $(MAIN_SCROLLABLE).scrollTop()){ $(document).trigger('hideAutocomplete'); }; $(MAIN_SCROLLABLE).data('lastScroll', $(MAIN_SCROLLABLE).scrollTop()) } }, with: selectedNotebook">
  376. <div class="row-fluid row-container sortable-snippets" data-bind="css: {'is-editing': $root.isEditing},
  377. sortable: {
  378. template: 'snippet${ suffix }',
  379. data: snippets,
  380. isEnabled: true,
  381. options: {
  382. 'handle': '.move-widget',
  383. 'axis' : 'y',
  384. 'opacity': 0.8,
  385. 'placeholder': 'snippet-move-placeholder',
  386. 'greedy': true,
  387. 'stop': function(event, ui) {
  388. var $element = $(event.target);
  389. $element.find('.snippet-body').slideDown('fast', function () { $(MAIN_SCROLLABLE).scrollTop(lastWindowScrollPosition); });
  390. },
  391. 'helper': function(event) {
  392. lastWindowScrollPosition = $(MAIN_SCROLLABLE).scrollTop();
  393. var $element = $(event.target);
  394. $element.find('.snippet-body').slideUp('fast', function () {
  395. $('.sortable-snippets').sortable('refreshPositions')
  396. });
  397. var _par = $('<div>')
  398. .css('overflow', 'hidden')
  399. .addClass('card-widget snippet-move-helper')
  400. .width($element.parents('.snippet').width());
  401. $('<h2>')
  402. .addClass('card-heading')
  403. .html($element.parents('h2').html())
  404. .appendTo(_par)
  405. .find('.hover-actions, .snippet-actions')
  406. .removeClass('hover-actions')
  407. .removeClass('snippet-actions');
  408. $('<pre>')
  409. .addClass('dragging-pre muted')
  410. .html(ko.dataFor($element.parents('.card-widget')[0]).statement())
  411. .appendTo(_par);
  412. _par.css('height', '100px');
  413. return _par;
  414. }
  415. },
  416. dragged: function (widget) {
  417. $('.snippet-body').slideDown('fast', function () { $(MAIN_SCROLLABLE).scrollTop(lastWindowScrollPosition); });
  418. }
  419. }">
  420. </div>
  421. % if hasattr(caller, "addSnippetHTML"):
  422. ${ caller.addSnippetHTML() }
  423. % endif
  424. </div>
  425. </script>
  426. <script type="text/html" id="snippetIcon${ suffix }">
  427. <!-- ko if: viewSettings().snippetImage -->
  428. <img class="snippet-icon-image" data-bind="attr: { 'src': viewSettings().snippetImage }" alt="${ _('Snippet icon') }">
  429. <!-- /ko -->
  430. <!-- ko if: viewSettings().snippetIcon -->
  431. <i class="fa snippet-icon" data-bind="css: viewSettings().snippetIcon"></i>
  432. <!-- /ko -->
  433. </script>
  434. <script type="text/html" id="query-tabs${ suffix }">
  435. <div class="query-history-container" data-bind="onComplete: function(){ redrawFixedHeaders(200); }">
  436. <div data-bind="delayedOverflow: 'slow', css: resultsKlass" style="margin-top: 5px; position: relative;">
  437. <ul class="nav nav-tabs nav-tabs-editor">
  438. <li data-bind="click: function(){ currentQueryTab('queryHistory'); }, css: {'active': currentQueryTab() == 'queryHistory'}, onClickOutside: function () { if ($parent.historyFilterVisible() && $parent.historyFilter() === '') { $parent.historyFilterVisible(false) } }">
  439. <a class="inactive-action" style="display:inline-block" href="#queryHistory" data-toggle="tab">${_('Query History')}</a>
  440. <div style="margin-left: -15px;" class="inline-block inactive-action pointer visible-on-hover" title="${_('Search the query history')}" data-bind="click: function(data, e){ $parent.historyFilterVisible(!$parent.historyFilterVisible()); if ($parent.historyFilterVisible()) { window.setTimeout(function(){ $(e.target).parent().siblings('input').focus(); }, 0); } else { $parent.historyFilter('') }}"><i class="snippet-icon fa fa-search"></i></div>
  441. <input class="input-small inline-tab-filter" type="text" data-bind="visible: $parent.historyFilterVisible, clearable: $parent.historyFilter, valueUpdate:'afterkeydown'" placeholder="${ _('Search...') }">
  442. <div class="dropdown inline-block inactive-action pointer visible-on-hover">
  443. <a class="" data-toggle="dropdown" href="javascript: void(0)">
  444. <i class="fa fa-fw fa-ellipsis-v"></i>
  445. </a>
  446. <ul class="dropdown-menu">
  447. <li data-bind="visible: $parent.history().length > 0">
  448. <!-- ko if: editorMode -->
  449. <a data-target="#clearHistoryModal${ suffix }" data-toggle="modal" rel="tooltip">
  450. <i class="fa fa-fw fa-calendar-times-o"></i> Clear
  451. </a>
  452. <!-- /ko -->
  453. <!-- ko ifnot: editorMode --><!-- /ko -->
  454. </li>
  455. <li><a href="javascript:void(0);" data-bind="click: exportHistory.bind($data)"><i class="fa fa-fw fa-download"></i> ${_('Export')}</a></li>
  456. <li><a href="javascript:void(0);" data-bind="publish: { 'show.import.documents.modal': { importedCallback: refreshHistory.bind($data.parentNotebook), isHistory: true }}"><i class="fa fa-fw fa-upload"></i> ${_('Import' )}</a></li>
  457. </ul>
  458. </div>
  459. </li>
  460. <li class="margin-right-20" data-bind="click: function(){ currentQueryTab('savedQueries'); }, css: {'active': currentQueryTab() == 'savedQueries'}, onClickOutside: function () { if (queriesFilterVisible() && queriesFilter() === '') { queriesFilterVisible(false) } }">
  461. <a class="inactive-action" style="display:inline-block" href="#savedQueries" data-toggle="tab">${_('Saved Queries')}</a>
  462. <div style="margin-left: -15px;" class="inline-block inactive-action pointer visible-on-hover" title="${_('Search the saved queries')}" data-bind="visible: !queriesHasErrors(), click: function(data, e){ queriesFilterVisible(!queriesFilterVisible()); if (queriesFilterVisible()) { window.setTimeout(function(){ $(e.target).parent().siblings('input').focus(); }, 0); } else { queriesFilter('') }}"><i class="snippet-icon fa fa-search"></i></div>
  463. <input class="input-small inline-tab-filter" type="text" data-bind="visible: queriesFilterVisible, clearable: queriesFilter, valueUpdate:'afterkeydown'" placeholder="${ _('Search...') }">
  464. </li>
  465. % if ENABLE_QUERY_BUILDER.get():
  466. <!-- ko if: isSqlDialect -->
  467. <li style="margin-right: 25px;" data-bind="click: function(){ currentQueryTab('queryBuilderTab'); }, css: {'active': currentQueryTab() == 'queryBuilderTab'}"><a class="inactive-action" href="#queryBuilderTab" data-toggle="tab">${_('Query Builder')}</a></li>
  468. <!-- /ko -->
  469. % endif
  470. <li data-bind="click: function(){ currentQueryTab('queryResults'); }, css: {'active': currentQueryTab() == 'queryResults'}">
  471. <a class="inactive-action" style="display:inline-block" href="#queryResults" data-toggle="tab">${_('Results')}
  472. ## <!-- ko if: result.rows() != null -->
  473. ## (<span data-bind="text: result.rows().toLocaleString() + (type() == 'impala' && result.rows() == 1024 ? '+' : '')" title="${ _('Number of rows') }"></span>)
  474. ## <!-- /ko -->
  475. </a>
  476. </li>
  477. ## <!-- ko if: result.explanation().length > 0 -->
  478. ## <li data-bind="click: function(){ currentQueryTab('queryExplain'); }, css: {'active': currentQueryTab() == 'queryExplain'}"><a class="inactive-action" href="#queryExplain" data-toggle="tab">${_('Explain')}</a></li>
  479. ## <!-- /ko -->
  480. <!-- ko foreach: pinnedContextTabs -->
  481. <li data-bind="click: function() { $parent.currentQueryTab(tabId) }, css: { 'active': $parent.currentQueryTab() === tabId }">
  482. <a class="inactive-action" data-toggle="tab" data-bind="attr: { 'href': '#' + tabId }">
  483. <i class="snippet-icon fa" data-bind="css: iconClass"></i> <span data-bind="text: title"></span>
  484. <div class="inline-block inactive-action margin-left-10 pointer" data-bind="click: function () { $parent.removeContextTab($data); }">
  485. <i class="snippet-icon fa fa-times"></i>
  486. </div>
  487. </a>
  488. </li>
  489. <!-- /ko -->
  490. <!-- ko if: HAS_WORKLOAD_ANALYTICS && type() === 'impala' -->
  491. <li data-bind="visible: showExecutionAnalysis, click: function(){ currentQueryTab('executionAnalysis'); }, css: {'active': currentQueryTab() == 'executionAnalysis'}"><a class="inactive-action" href="#executionAnalysis" data-toggle="tab" data-bind="click: function(){ $('a[href=\'#executionAnalysis\']').tab('show'); }, event: {'shown': fetchExecutionAnalysis }"><span>${_('Execution Analysis')} </span><span></span></a></li>
  492. <!-- /ko -->
  493. </ul>
  494. <div class="tab-content" style="border: none; overflow-x: hidden">
  495. <div class="tab-pane" id="queryHistory" style="min-height: 80px;" data-bind="css: {'active': currentQueryTab() == 'queryHistory'}, style: { 'height' : $parent.historyInitialHeight() > 0 ? Math.max($parent.historyInitialHeight(), 40) + 'px' : '' }">
  496. <!-- ko if: $parent.loadingHistory -->
  497. <div class="margin-top-10 margin-left-10">
  498. <i class="fa fa-spinner fa-spin muted"></i>
  499. </div>
  500. <!-- /ko -->
  501. <!-- ko ifnot: $parent.loadingHistory -->
  502. <!-- ko if: $parent.history().length === 0 && $parent.historyFilter() === '' -->
  503. <div class="margin-top-10 margin-left-10" style="font-style: italic">${ _("No queries to be shown.") }</div>
  504. <!-- /ko -->
  505. <!-- ko if: $parent.history().length === 0 && $parent.historyFilter() !== '' -->
  506. <div class="margin-top-10 margin-left-10" style="font-style: italic">${ _('No queries found for') } <strong data-bind="text: $parent.historyFilter"></strong>.</div>
  507. <!-- /ko -->
  508. <!-- ko if: $parent.history().length > 0 -->
  509. <table class="table table-condensed margin-top-10 history-table">
  510. <tbody data-bind="foreach: { data: $parent.history, afterRender: function(){ huePubSub.publish('editor.calculate.history.height'); } }">
  511. <tr data-bind="click: function() { if (uuid() != $root.selectedNotebook().uuid()) { $root.openNotebook(uuid()); } }, css: { 'highlight': uuid() == $root.selectedNotebook().uuid(), 'pointer': uuid() != $root.selectedNotebook().uuid() }">
  512. <td style="width: 100px" class="muted" data-bind="style: {'border-top-width': $index() == 0 ? '0' : ''}">
  513. <span data-bind="momentFromNow: {data: lastExecuted, interval: 10000, titleFormat: 'LLL'}"></span>
  514. </td>
  515. <td style="width: 25px" class="muted" data-bind="style: {'border-top-width': $index() == 0 ? '0' : ''}">
  516. <!-- ko switch: status -->
  517. <!-- ko case: 'running' -->
  518. <div class="history-status" data-bind="tooltip: { title: '${ _ko("Query running") }', placement: 'bottom' }"><i class="fa fa-fighter-jet fa-fw"></i></div>
  519. <!-- /ko -->
  520. <!-- ko case: 'failed' -->
  521. <div class="history-status" data-bind="tooltip: { title: '${ _ko("Query failed") }', placement: 'bottom' }"><i class="fa fa-exclamation fa-fw"></i></div>
  522. <!-- /ko -->
  523. <!-- ko case: 'available' -->
  524. <div class="history-status" data-bind="tooltip: { title: '${ _ko("Result available") }', placement: 'bottom' }"><i class="fa fa-check fa-fw"></i></div>
  525. <!-- /ko -->
  526. <!-- ko case: 'expired' -->
  527. <div class="history-status" data-bind="tooltip: { title: '${ _ko("Result expired") }', placement: 'bottom' }"><i class="fa fa-unlink fa-fw"></i></div>
  528. <!-- /ko -->
  529. <!-- /ko -->
  530. </td>
  531. <td style="width: 25px" class="muted" data-bind="ellipsis: {data: name(), length: 30}, style: {'border-top-width': $index() == 0 ? '0' : ''}"></td>
  532. <td data-bind="style: {'border-top-width': $index() == 0 ? '0' : ''}, click: function(){ if (window.getSelection().toString() === '' && uuid() != $root.selectedNotebook().uuid()) { $root.openNotebook(uuid()) } }, clickBubble: false"><div data-bind="highlight: { value: query, dialect: $parent.type }"></div></td>
  533. </tr>
  534. </tbody>
  535. </table>
  536. <!-- /ko -->
  537. <!-- ko with: $parent -->
  538. <div class="pagination" data-bind="visible: historyTotalPages() > 1">
  539. <ul>
  540. <li data-bind="css: { 'disabled' : historyCurrentPage() === 1 }"><a href="javascript: void(0);" data-bind="click: function() { prevHistoryPage(); }">${ _("Prev") }</a></li>
  541. <li class="active"><span data-bind="text: historyCurrentPage() + '/' + historyTotalPages()"></span></li>
  542. <li data-bind="css: { 'disabled' : historyCurrentPage() === historyTotalPages() }"><a href="javascript: void(0);" data-bind="click: function() { nextHistoryPage(); }">${ _("Next") }</a></li>
  543. </ul>
  544. </div>
  545. <!-- /ko -->
  546. <!-- /ko -->
  547. </div>
  548. <div class="tab-pane" id="savedQueries" data-bind="css: {'active': currentQueryTab() == 'savedQueries'}" style="overflow: hidden">
  549. <!-- ko if: loadingQueries -->
  550. <div class="margin-top-10 margin-left-10">
  551. <i class="fa fa-spinner fa-spin muted"></i>
  552. </div>
  553. <!-- /ko -->
  554. <!-- ko if: queriesHasErrors() -->
  555. <div class="margin-top-10 margin-left-10" style="font-style: italic">${ _("Error loading my queries") }</div>
  556. <!-- /ko -->
  557. <!-- ko if: !queriesHasErrors() && !loadingQueries() && queries().length === 0 && queriesFilter() === '' -->
  558. <div class="margin-top-10 margin-left-10" style="font-style: italic">${ _("You don't have any saved query.") }</div>
  559. <!-- /ko -->
  560. <!-- ko if: !queriesHasErrors() && !loadingQueries() && queries().length === 0 && queriesFilter() !== '' -->
  561. <div class="margin-top-10 margin-left-10" style="font-style: italic">${ _('No queries found for') } <strong data-bind="text: queriesFilter"></strong>.</div>
  562. <!-- /ko -->
  563. <!-- ko if: !queriesHasErrors() && !loadingQueries() && queries().length > 0 -->
  564. <table class="table table-condensed margin-top-10 history-table">
  565. <thead>
  566. <tr>
  567. <th style="width: 16%">${ _("Name") }</th>
  568. <th style="width: 50%">${ _("Description") }</th>
  569. <th style="width: 18%">${ _("Owner") }</th>
  570. <th style="width: 16%">${ _("Last Modified") }</th>
  571. </tr>
  572. </thead>
  573. <tbody data-bind="foreach: queries">
  574. <tr data-bind="click: function() { if (uuid() != $root.selectedNotebook().uuid()) { $root.openNotebook(uuid(), 'savedQueries'); } }, css: { 'highlight': uuid() == $root.selectedNotebook().uuid(), 'pointer': uuid() != $root.selectedNotebook().uuid() }">
  575. <td style="width: 16%"><span data-bind="ellipsis: {data: name(), length: 50}"></span></td>
  576. <td style="width: 50%; white-space: normal"><span data-bind="text: description"></span></td>
  577. <td style="width: 18%"><span data-bind="text: owner"></span></td>
  578. <td style="width: 16%"><span data-bind="text: localeFormat(last_modified())"></span></td>
  579. </tr>
  580. </tbody>
  581. </table>
  582. <!-- /ko -->
  583. <div class="pagination" data-bind="visible: queriesTotalPages() > 1">
  584. <ul>
  585. <li data-bind="css: { 'disabled' : queriesCurrentPage() === 1 }"><a href="javascript: void(0);" data-bind="click: prevQueriesPage">${ _("Prev") }</a></li>
  586. <li class="active"><span data-bind="text: queriesCurrentPage() + '/' + queriesTotalPages()"></span></li>
  587. <li data-bind="css: { 'disabled' : queriesCurrentPage() === queriesTotalPages() }"><a href="javascript: void(0);" data-bind="click: nextQueriesPage">${ _("Next") }</a></li>
  588. </ul>
  589. </div>
  590. </div>
  591. % if ENABLE_QUERY_BUILDER.get():
  592. <div class="tab-pane margin-top-10" id="queryBuilderTab" data-bind="css: {'active': currentQueryTab() == 'queryBuilderTab'}">
  593. <div id="queryBuilderAlert" style="display: none" class="alert">${ _('There are currently no rules defined. To get started, right click on any table column in the SQL Assist panel.') }</div>
  594. <table id="queryBuilder" class="table table-condensed">
  595. <thead>
  596. <tr>
  597. <th width="10%">${ _('Table') }</th>
  598. <th>${ _('Column') }</th>
  599. <th width="10%">${ _('Operation') }</th>
  600. <th width="5%">&nbsp;</th>
  601. <th width="1%">&nbsp;</th>
  602. </tr>
  603. </thead>
  604. </table>
  605. <div class="button-panel">
  606. <button class="btn btn-primary disable-feedback" data-bind="click: generateQuery">${_('Build query')}</button>
  607. </div>
  608. </div>
  609. % endif
  610. <div class="tab-pane" id="queryResults" data-bind="css: {'active': currentQueryTab() == 'queryResults'}">
  611. <!-- ko if: ['text', 'jar', 'py', 'markdown'].indexOf(type()) === -1 -->
  612. <!-- ko component: { name: 'snippet-results', params: {
  613. activeExecutable: activeExecutable,
  614. editorMode: parentVm.editorMode,
  615. id: id,
  616. isPresentationMode: parentNotebook.isPresentationMode,
  617. isResultFullScreenMode: parentVm.isResultFullScreenMode,
  618. resultsKlass: resultsKlass
  619. }} --><!-- /ko -->
  620. <!-- /ko -->
  621. </div>
  622. ## <!-- ko if: result.explanation().length > 0 -->
  623. ## <div class="tab-pane" id="queryExplain" data-bind="css: {'active': currentQueryTab() == 'queryExplain'}">
  624. ## <!-- ko template: { name: 'snippet-explain${ suffix }' } --><!-- /ko -->
  625. ## </div>
  626. ## <!-- /ko -->
  627. <!-- ko if: HAS_WORKLOAD_ANALYTICS && type() === 'impala' -->
  628. <div class="tab-pane" id="executionAnalysis" data-bind="css: {'active': currentQueryTab() == 'executionAnalysis'}" style="padding: 10px;">
  629. <!-- ko component: { name: 'hue-execution-analysis' } --><!-- /ko -->
  630. </div>
  631. <!-- /ko -->
  632. <!-- ko foreach: pinnedContextTabs -->
  633. <div class="tab-pane" style="height: 300px; position: relative; overflow: hidden;" data-bind="attr: { 'id': tabId }, css: {'active': $parent.currentQueryTab() === tabId }">
  634. <div style="display: flex; flex-direction: column; margin-top: 10px; overflow: hidden; height: 100%; position: relative;" data-bind="template: 'context-popover-contents'"></div>
  635. </div>
  636. <!-- /ko -->
  637. </div>
  638. </div>
  639. </div>
  640. </script>
  641. <script type="text/html" id="doc-search-autocomp-item">
  642. <a>
  643. <div>
  644. <strong style="font-size: 14px;" data-bind="html: name"></strong>
  645. <div style="width: 190px; overflow: hidden; white-space: nowrap; text-overflow:ellipsis; font-size: 12px;" class="muted" data-bind="text: description"></div>
  646. </div>
  647. </a>
  648. </script>
  649. <script type="text/html" id="longer-operation${ suffix }">
  650. <div rel="tooltip" data-placement="bottom" data-bind="tooltip, fadeVisible: showLongOperationWarning" title="${ _('The query is hanging and taking longer than expected.') }" class="inline-block margin-right-10">
  651. <i class="fa fa-exclamation-triangle warning"></i>
  652. </div>
  653. </script>
  654. <script type="text/html" id="query-redacted${ suffix }">
  655. <div rel="tooltip" data-placement="bottom" data-bind="tooltip, fadeVisible: is_redacted" title="${ _('The current query has been redacted to hide sensitive information.') }" class="inline-block margin-right-10">
  656. <i class="fa fa-low-vision warning"></i>
  657. </div>
  658. </script>
  659. <script type="text/html" id="notebook-snippet-header${ suffix }">
  660. <!-- ko if: $root.isPresentationMode() || $root.isResultFullScreenMode() -->
  661. <div class="inline">
  662. <!-- ko if: name() -->
  663. <span data-bind="text: name"></span>
  664. <!-- /ko -->
  665. <!-- ko if: !name() && !$root.isHidingCode() -->
  666. <span>${ _("Add -- comments on top of the SQL statement to display a title") }</span>
  667. <!-- /ko -->
  668. </div>
  669. <!-- /ko -->
  670. <!-- ko if: ! $root.isPresentationMode() && ! $root.isResultFullScreenMode() -->
  671. <div class="inactive-action hover-actions inline">
  672. <span class="inactive-action" data-bind="css: { 'empty-title': name() === '' }, editable: name, editableOptions: { emptytext: '${_ko('My Snippet')}', mode: 'inline', enabled: true, placement: 'right' }" style="border:none;color: #DDD"></span>
  673. </div>
  674. <div class="hover-actions inline pull-right" style="font-size: 15px;">
  675. <!-- ko template: { name: 'query-redacted${ suffix }' } --><!-- /ko -->
  676. <!-- ko template: { name: 'longer-operation${ suffix }' } --><!-- /ko -->
  677. ## <span class="execution-timer" data-bind="visible: type() != 'text' && status() != 'ready' && status() != 'loading', text: result.executionTime().toHHMMSS()" title="${ _('Execution time') }"></span>
  678. <!-- ko template: { name: 'snippet-header-database-selection' } --><!-- /ko -->
  679. <a class="inactive-action move-widget" href="javascript:void(0)"><i class="fa fa-arrows"></i></a>
  680. <a class="inactive-action" href="javascript:void(0)" data-bind="toggle: settingsVisible, visible: hasProperties, css: { 'blue' : settingsVisible }" title="${ _('Snippet settings') }"><i class="fa fa-cog"></i></a>
  681. <a class="inactive-action" href="javascript:void(0)" data-bind="click: function(){ $root.removeSnippet($parent, $data); }"><i class="fa fa-times"></i></a>
  682. </div>
  683. <!-- /ko -->
  684. </script>
  685. <script type="text/html" id="editor-snippet-header${ suffix }">
  686. <div class="hover-actions inline pull-right" style="font-size: 15px; position: relative;" data-bind="style: { 'marginRight': $root.isPresentationMode() || $root.isResultFullScreenMode() ? '40px' : '0' }">
  687. <!-- ko template: { name: 'query-redacted${ suffix }' } --><!-- /ko -->
  688. <!-- ko template: { name: 'longer-operation${ suffix }' } --><!-- /ko -->
  689. ## <span class="execution-timer" data-bind="visible: type() != 'text' && status() != 'ready' && status() != 'loading', text: result.executionTime().toHHMMSS()" title="${ _('Execution time') }"></span>
  690. <!-- ko template: { name: 'snippet-header-database-selection' } --><!-- /ko -->
  691. <a class="inactive-action margin-left-10 pointer" title="${ _('Show editor help') }" data-toggle="modal" data-target="#helpModal${ suffix }"><i class="fa fa-question"></i></a>
  692. </div>
  693. </script>
  694. <script type="text/html" id="snippet-header-database-selection">
  695. <!-- ko if: isSqlDialect() || type() == 'spark2' -->
  696. <!-- ko component: {
  697. name: 'hue-context-selector',
  698. params: {
  699. sourceType: type,
  700. compute: compute,
  701. namespace: namespace,
  702. availableDatabases: availableDatabases,
  703. database: database,
  704. hideDatabases: !isSqlDialect()
  705. }
  706. } --><!-- /ko -->
  707. <!-- /ko -->
  708. </script>
  709. <script type="text/html" id="snippet${ suffix }">
  710. <div data-bind="visibleOnHover: { override: inFocus() || settingsVisible() || dbSelectionVisible() || $root.editorMode() || saveResultsModalVisible(), selector: '.hover-actions' }">
  711. <div class="snippet-container row-fluid" data-bind="visibleOnHover: { override: $root.editorMode() || inFocus() || saveResultsModalVisible(), selector: '.snippet-actions' }">
  712. <div class="snippet card card-widget" data-bind="css: {'notebook-snippet' : ! $root.editorMode(), 'editor-mode': $root.editorMode(), 'active-editor': inFocus, 'snippet-text' : type() == 'text'}, attr: {'id': 'snippet_' + id()}, clickForAceFocus: ace">
  713. <div style="position: relative;">
  714. <div class="snippet-row" style="position: relative;">
  715. <div class="snippet-body" data-bind="clickForAceFocus: ace, visible: ! $root.isResultFullScreenMode()">
  716. <h5 class="card-heading-print" data-bind="text: name, css: {'visible': name() != ''}"></h5>
  717. <h2 style="margin-left:5px;padding: 3px 0" class="card-heading simple" data-bind="dblclick: function(){ if (!$root.editorMode() && !$root.isPresentationMode()) { $parent.newSnippetAbove(id()) } }, clickForAceFocus: ace">
  718. <!-- ko template: { if: $root.editorMode(), name: 'editor-snippet-header${ suffix }' } --><!-- /ko -->
  719. <!-- ko template: { if: ! $root.editorMode(), name: 'notebook-snippet-header${ suffix }' } --><!-- /ko -->
  720. </h2>
  721. <!-- ko template: { if: ['text', 'jar', 'java', 'spark2', 'distcp', 'shell', 'mapreduce', 'py', 'markdown'].indexOf(type()) == -1, name: 'code-editor-snippet-body${ suffix }' } --><!-- /ko -->
  722. <!-- ko template: { if: type() == 'text', name: 'text-snippet-body${ suffix }' } --><!-- /ko -->
  723. <!-- ko template: { if: type() == 'markdown', name: 'markdown-snippet-body${ suffix }' } --><!-- /ko -->
  724. <!-- ko template: { if: ['java', 'distcp', 'shell', 'mapreduce', 'jar', 'py', 'spark2'].indexOf(type()) != -1, name: 'executable-snippet-body${ suffix }' } --><!-- /ko -->
  725. </div>
  726. <div style="position: absolute; top:25px; width: 100%" data-bind="style: { 'z-index': 400 - $index() }">
  727. <!-- ko template: 'snippet-settings${ suffix }' --><!-- /ko -->
  728. </div>
  729. </div>
  730. <!-- ko template: { if: ['text', 'markdown'].indexOf(type()) == -1, name: 'snippet-execution-status${ suffix }' } --><!-- /ko -->
  731. <!-- ko template: { if: $root.editorMode() && ! $root.isResultFullScreenMode() && ['jar', 'java', 'spark2', 'distcp', 'shell', 'mapreduce', 'py'].indexOf(type()) == -1, name: 'snippet-code-resizer${ suffix }' } --><!-- /ko -->
  732. <div class="snippet-footer-actions">
  733. <!-- ko template: { if: ! $root.editorMode() && ! $root.isPresentationMode() && ! $root.isResultFullScreenMode(), name: 'notebook-snippet-type-controls${ suffix }' } --><!-- /ko -->
  734. <!-- ko template: { if: ['text', 'markdown'].indexOf(type()) == -1 && ! $root.isResultFullScreenMode(), name: 'snippet-execution-controls${ suffix }' } --><!-- /ko -->
  735. </div>
  736. <!-- ko if: !$root.isResultFullScreenMode() -->
  737. <!-- ko component: { name: 'executable-logs', params: {
  738. activeExecutable: activeExecutable,
  739. showLogs: showLogs,
  740. resultsKlass: resultsKlass,
  741. isPresentationMode: parentNotebook.isPresentationMode,
  742. isHidingCode: parentNotebook.isHidingCode
  743. }} --><!-- /ko -->
  744. <!-- /ko -->
  745. <!-- ko if: $root.editorMode() -->
  746. <!-- ko template: 'query-tabs${ suffix }' --><!-- /ko -->
  747. <!-- /ko -->
  748. <!-- ko if: !$root.editorMode() && ['text', 'jar', 'java', 'distcp', 'shell', 'mapreduce', 'py', 'markdown'].indexOf(type()) === -1 -->
  749. <!-- ko component: { name: 'snippet-results', params: {
  750. activeExecutable: activeExecutable,
  751. editorMode: parentVm.editorMode,
  752. id: id,
  753. isPresentationMode: parentNotebook.isPresentationMode,
  754. isResultFullScreenMode: parentVm.isResultFullScreenMode,
  755. resultsKlass: resultsKlass
  756. }} --><!-- /ko -->
  757. <!-- /ko -->
  758. <div class="clearfix"></div>
  759. </div>
  760. </div>
  761. </div>
  762. </div>
  763. </script>
  764. <script type="text/html" id="snippet-settings${ suffix }">
  765. <div class="snippet-settings" data-bind="slideVisible: settingsVisible" style="position: relative; z-index: 100;">
  766. <div class="snippet-settings-header">
  767. <h4><i class="fa fa-cog"></i> ${ _('Settings') }</h4>
  768. </div>
  769. <div class="snippet-settings-body">
  770. <form class="form-horizontal">
  771. % if ENABLE_EXTERNAL_STATEMENT.get():
  772. <!-- ko if: isSqlDialect -->
  773. <div class="config-property">
  774. <label class="config-label">${ _('Type') }</label>
  775. <div class="config-controls">
  776. <div style="padding-top: 4px; display: inline-block;" data-bind="component: { name: 'hue-drop-down', params: { value: statementType, entries: statementTypes, linkTitle: '${ _ko('Statement type') }' } }"></div>
  777. </div>
  778. </div>
  779. <!-- /ko -->
  780. % endif
  781. <!-- ko template: { if: typeof properties().driverCores != 'undefined', name: 'property', data: { type: 'number', label: '${ _ko('Driver Cores') }', value: properties().driverCores, title: '${ _ko('Number of cores used by the driver, only in cluster mode (Default: 1)') }'}} --><!-- /ko -->
  782. <!-- ko template: { if: typeof properties().executorCores != 'undefined', name: 'property', data: { type: 'number', label: '${ _ko('Executor Cores') }', value: properties().executorCores, title: '${ _ko('Number of cores per executor (Default: 1)') }' }} --><!-- /ko -->
  783. <!-- ko template: { if: typeof properties().numExecutors != 'undefined', name: 'property', data: { type: 'number', label: '${ _ko('Executors') }', value: properties().numExecutors, title: '${ _ko('Number of executors to launch (Default: 2)') }' }} --><!-- /ko -->
  784. <!-- ko template: { if: typeof properties().queue != 'undefined', name: 'property', data: { type: 'string', label: '${ _ko('Queue') }', value: properties().queue, title: '${ _ko('The YARN queue to submit to (Default: default)') }' }} --><!-- /ko -->
  785. <!-- ko template: { if: typeof properties().archives != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko('Archives') }', value: properties().archives, title: '${ _ko('Archives to be extracted into the working directory of each executor (YARN only)') }', placeholder: '${ _ko('e.g. file.zip') }'}} --><!-- /ko -->
  786. <!-- ko template: { if: typeof properties().files != 'undefined', name: 'property', data: { type: 'hdfs-files', label: '${ _ko('Files') }', value: properties().files, visibleObservable: settingsVisible, title: '${ _ko('Files to be placed in the working directory of each executor.') }'}} --><!-- /ko -->
  787. <!-- ko template: { if: typeof properties().functions != 'undefined', name: 'property', data: { type: 'functions', label: '${ _ko('Functions') }', value: properties().functions, visibleObservable: settingsVisible, title: '${ _ko('UDFs name and class') }'}} --><!-- /ko -->
  788. <!-- ko template: { if: typeof properties().settings != 'undefined', name: 'property', data: { type: 'settings', label: '${ _ko('Settings') }', value: properties().settings, visibleObservable: settingsVisible, title: '${ _ko('Properties') }'}} --><!-- /ko -->
  789. <!-- ko template: { if: typeof properties().spark_opts != 'undefined', name: 'property', data: { type: 'csv', label: '${ _ko('Spark Arguments') }', value: properties().spark_opts, title: '${ _ko('Names and values of Spark parameters') }', placeholder: '${ _ko('e.g. --executor-memory 20G --num-executors 50') }'}} --><!-- /ko -->
  790. <!-- ko template: { if: typeof properties().parameters != 'undefined', name: 'property', data: { type: 'csv', label: '${ _ko('Parameters') }', value: properties().parameters, title: '${ _ko('Names and values of Pig parameters and options') }', placeholder: '${ _ko('e.g. input /user/data, -param input=/user/data, -optimizer_off SplitFilter, -verbose') }'}} --><!-- /ko -->
  791. <!-- ko template: { if: typeof properties().hadoopProperties != 'undefined', name: 'property', data: { type: 'csv', label: '${ _ko('Hadoop properties') }', value: properties().hadoopProperties, title: '${ _ko('Name and values of Hadoop properties') }', placeholder: '${ _ko('e.g. mapred.job.queue.name=production, mapred.map.tasks.speculative.execution=false') }'}} --><!-- /ko -->
  792. <!-- ko template: { if: typeof properties().resources != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko('Resources') }', value: properties().resources, title: '${ _ko('HDFS Files or compressed files') }', placeholder: '${ _ko('e.g. /tmp/file, /tmp.file.zip') }'}} --><!-- /ko -->
  793. <!-- ko template: { if: typeof properties().capture_output != 'undefined', name: 'property', data: { type: 'boolean', label: '${ _ko('Capture output') }', value: properties().capture_output, title: '${ _ko('If capturing the output of the shell script') }' }} --><!-- /ko -->
  794. </form>
  795. </div>
  796. <a class="pointer demi-modal-chevron" data-bind="click: function() { settingsVisible(! settingsVisible()) }"><i class="fa fa-chevron-up"></i></a>
  797. </div>
  798. </script>
  799. <script type="text/html" id="code-editor-snippet-body${ suffix }">
  800. <!-- ko if: HAS_OPTIMIZER && (type() == 'impala' || type() == 'hive') && ! $root.isPresentationMode() && ! $root.isResultFullScreenMode() -->
  801. <div class="optimizer-container" data-bind="css: { 'active': showOptimizer }">
  802. <!-- ko if: hasSuggestion() -->
  803. <!-- ko with: suggestion() -->
  804. <!-- ko if: parseError -->
  805. <!-- ko if: $parent.compatibilityTargetPlatform().value === $parent.type() && $parent.compatibilitySourcePlatform().value === $parent.type() -->
  806. <div class="optimizer-icon error" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
  807. <i class="fa fa-exclamation"></i>
  808. </div>
  809. <!-- ko if: $parent.showOptimizer -->
  810. <span class="optimizer-explanation alert-error alert-neutral">${ _('The query has a parse error.') }</span>
  811. <!-- /ko -->
  812. <!-- /ko -->
  813. ## Oracle, MySQL compatibility... as they return a parseError and not encounteredString.
  814. <!-- ko if: $parent.compatibilityTargetPlatform().value !== $parent.type() || $parent.type() !== $parent.compatibilitySourcePlatform().value -->
  815. <div class="optimizer-icon warning" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
  816. <i class="fa fa-exclamation"></i>
  817. </div>
  818. <!-- ko if: $parent.showOptimizer -->
  819. <span class="optimizer-explanation alert-warning alert-neutral">${ _('This ') } <span data-bind="text: $parent.compatibilitySourcePlatform().name"></span> ${ _(' query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
  820. <!-- /ko -->
  821. <!-- /ko -->
  822. <!-- /ko -->
  823. <!-- ko if: !parseError() && ($parent.compatibilityTargetPlatform().value !== $parent.type() || $parent.compatibilitySourcePlatform().value !== $parent.type()) -->
  824. <!-- ko if: queryError.encounteredString().length == 0 -->
  825. <div class="optimizer-icon success" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
  826. <i class="fa fa-check"></i>
  827. </div>
  828. <!-- ko if: $parent.showOptimizer -->
  829. <span class="optimizer-explanation alert-success alert-neutral">
  830. ${ _('The ') } <div data-bind="component: { name: 'hue-drop-down', params: { value: $parent.compatibilitySourcePlatform, entries: $parent.compatibilitySourcePlatforms, labelAttribute: 'name' } }" style="display: inline-block"></div>
  831. <!-- ko if: $parent.compatibilitySourcePlatform().value === $parent.type() -->
  832. ${ _(' query is compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.
  833. <a href="javascript:void(0)" data-bind="click: function() { $parent.type($parent.compatibilityTargetPlatform().value); }">${ _('Execute it with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span></a>.
  834. <!-- /ko -->
  835. <!-- ko if: $parent.compatibilitySourcePlatform().value !== $parent.type() -->
  836. ${ _(' query is compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.
  837. <!-- /ko -->
  838. </span>
  839. <!-- /ko -->
  840. <!-- /ko -->
  841. <!-- ko ifnot: queryError.encounteredString().length == 0 -->
  842. <div class="optimizer-icon warning" data-bind="click: function(){ $parent.showOptimizer(! $parent.showOptimizer()) }, attr: { 'title': $parent.showOptimizer() ? '${ _ko('Close Validator') }' : '${ _ko('Open Validator') }'}">
  843. <i class="fa fa-exclamation"></i>
  844. </div>
  845. <!-- ko if: $parent.showOptimizer -->
  846. <span class="optimizer-explanation alert-warning alert-neutral">${ _('This query is not compatible with ') } <span data-bind="text: $parent.compatibilityTargetPlatform().name"></span>.</span>
  847. <!-- /ko -->
  848. <!-- /ko -->
  849. <!-- /ko -->
  850. <!-- /ko -->
  851. <!-- /ko -->
  852. <!-- ko if: ! hasSuggestion() && topRisk() -->
  853. <!-- ko if: topRisk().risk === 'low' -->
  854. <div class="optimizer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some low risks were detected, see the assistant for details.') }">
  855. <i class="fa fa-check"></i>
  856. </div>
  857. <!-- /ko -->
  858. <!-- ko if: topRisk().risk == 'medium' -->
  859. <div class="optimizer-icon warning" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some medium risks were detected, see the assistant for details.') }">
  860. <i class="fa fa-exclamation"></i>
  861. </div>
  862. <!-- /ko -->
  863. <!-- ko if: topRisk().risk == 'high' -->
  864. <div class="optimizer-icon error" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Some high risks were detected, see the assistant for details.') }">
  865. <i class="fa fa-exclamation"></i>
  866. </div>
  867. <!-- /ko -->
  868. <!-- /ko -->
  869. <!-- ko if: hasSuggestion() == '' && ! topRisk() -->
  870. <div class="optimizer-icon success" data-bind="click: function () { huePubSub.publish('assist.highlight.risk.suggestions'); }, tooltip: { placement: 'bottom' }" title="${ _('Query validated, no issues found.') }">
  871. <i class="fa fa-check"></i>
  872. </div>
  873. <!-- /ko -->
  874. </div>
  875. <!-- /ko -->
  876. <div class="row-fluid" style="margin-bottom: 5px">
  877. <div class="editor span12" data-bind="css: {'single-snippet-editor ace-container-resizable' : $root.editorMode() }, clickForAceFocus: ace, visible: ! $root.isResultFullScreenMode() && ! ($root.isPresentationMode() && $root.isHidingCode())">
  878. <!-- ko if: statementType() == 'file' -->
  879. <div class="margin-top-10">
  880. <label class="pull-left" style="margin-top: 6px;margin-right: 10px;">${_('Query File')}</label>
  881. <input type="text" class="pull-left input-xxlarge filechooser-input" data-bind="value: statementPath, valueUpdate: 'afterkeydown', filechooser: statementPath, filechooserOptions: { skipInitialPathIfEmpty: true, linkMarkup: true }" placeholder="${ _('Path to file, e.g. /user/hue/sample.sql') }"/>
  882. <!-- ko if: statementPath() -->
  883. <div class="inline-block" style="margin-top: 4px">
  884. <a data-bind="hueLink: '/filebrowser/view=' + statementPath()" title="${ _('Open') }">
  885. <i class="fa fa-external-link-square"></i>
  886. </a>
  887. </div>
  888. <a class="btn" data-bind="click: function() { getExternalStatement(); }"><i class="fa fa-lg fa-refresh"></i></a>
  889. <!-- /ko -->
  890. </div>
  891. <div class="clearfix margin-bottom-20"></div>
  892. <!-- /ko -->
  893. <!-- ko if: statementType() == 'document' -->
  894. <div class="margin-top-10">
  895. <!-- ko if: associatedDocumentLoading -->
  896. <i class="fa fa-spinner fa-spin muted"></i>
  897. <!-- /ko -->
  898. <label class="pull-left" style="margin-top: 6px;margin-right: 10px;" data-bind="visible: !associatedDocumentLoading()">${_('Document')}</label>
  899. <div class="selectize-wrapper" style="width: 300px;" data-bind="visible: !associatedDocumentLoading()">
  900. <select placeholder="${ _('Search your documents...') }" data-bind="documentChooser: { loading: associatedDocumentLoading, value: associatedDocumentUuid, document: associatedDocument, type: type }"></select>
  901. </div>
  902. <!-- ko if: associatedDocument() -->
  903. <div class="pull-left" style="margin-top: 4px">
  904. <a data-bind="hueLink: associatedDocument().absoluteUrl" title="${ _('Open') }">
  905. <i class="fa fa-external-link-square"></i>
  906. </a>
  907. <span data-bind='text: associatedDocument().description' style="padding: 3px; margin-top: 2px" class="muted"></span>
  908. </div>
  909. <!-- /ko -->
  910. </div>
  911. <div class="clearfix margin-bottom-20"></div>
  912. <!-- /ko -->
  913. <div class="ace-editor" data-bind="
  914. visible: statementType() === 'text' || statementType() !== 'text' && externalStatementLoaded(),
  915. css: {
  916. 'single-snippet-editor ace-editor-resizable' : $root.editorMode(),
  917. 'active-editor': inFocus
  918. },
  919. attr: {
  920. id: id()
  921. },
  922. delayedOverflow: 'slow',
  923. aceEditor: {
  924. snippet: $data,
  925. contextTooltip: '${ _ko("Right-click for details") }',
  926. expandStar: '${ _ko("Right-click to expand with columns") }',
  927. ## highlightedRange: result.statement_range,
  928. readOnly: $root.isPresentationMode(),
  929. aceOptions: {
  930. showLineNumbers: $root.editorMode(),
  931. showGutter: $root.editorMode(),
  932. maxLines: $root.editorMode() ? null : 25,
  933. minLines: $root.editorMode() ? null : 3
  934. }
  935. },
  936. style: {
  937. 'opacity': statementType() !== 'text' || $root.isPresentationMode() ? '0.75' : '1',
  938. 'min-height': $root.editorMode() ? '0' : '48px',
  939. 'top': $root.editorMode() && statementType() !== 'text' ? '60px' : '0'
  940. }
  941. "></div>
  942. <!-- ko component: { name: 'hueAceAutocompleter', params: { editor: ace.bind($data), snippet: $data } } --><!-- /ko -->
  943. <ul class="table-drop-menu hue-context-menu">
  944. <li class="editor-drop-value"><a href="javascript:void(0);">"<span class="editor-drop-identifier"></span>"</a></li>
  945. <li class="divider"></li>
  946. <li class="editor-drop-select"><a href="javascript:void(0);">SELECT FROM <span class="editor-drop-identifier"></span>...</a></li>
  947. <li class="editor-drop-insert"><a href="javascript:void(0);">INSERT INTO <span class="editor-drop-identifier"></span>...</a></li>
  948. <li class="editor-drop-update"><a href="javascript:void(0);">UPDATE <span class="editor-drop-identifier"></span>...</a></li>
  949. <li class="editor-drop-drop"><a href="javascript:void(0);">DROP TABLE <span class="editor-drop-identifier"></span>...</a></li>
  950. <li class="editor-drop-view"><a href="javascript:void(0);">DROP VIEW <span class="editor-drop-identifier"></span>...</a></li>
  951. </ul>
  952. </div>
  953. <div class="clearfix"></div>
  954. <!-- ko template: { if: ! $root.isPresentationMode() && ! $root.isResultFullScreenMode(), name: 'snippet-variables' }--><!-- /ko -->
  955. </div>
  956. <div class="clearfix"></div>
  957. </script>
  958. <script type="text/html" id="notebook-actions">
  959. <div class="btn-group">
  960. <!-- ko if: $root.selectedNotebook() -->
  961. <!-- ko with: $root.selectedNotebook() -->
  962. <a class="btn" rel="tooltip" data-placement="bottom" title="${ _("Execute all") }" data-bind="visible: ! isExecutingAll(), click: function() { executeAll(); }">
  963. <i class="fa fa-fw fa-play"></i>
  964. </a>
  965. <!-- ko if: ! (snippets()[executingAllIndex()] && snippets()[executingAllIndex()].isCanceling()) -->
  966. <a class="btn red" rel="tooltip" data-placement="bottom" title="${ _("Stop all") }" data-bind="visible: isExecutingAll(), click: function() { cancelExecutingAll(); }">
  967. <i class="fa fa-fw fa-stop"></i>
  968. </a>
  969. <!-- /ko -->
  970. <!-- ko if: snippets()[executingAllIndex()] && snippets()[executingAllIndex()].isCanceling() -->
  971. <a class="btn" style="cursor: default;" title="${ _('Canceling operation...') }">
  972. <i class="fa fa-fw fa-spinner snippet-side-single fa-spin"></i>
  973. </a>
  974. <!-- /ko -->
  975. <!-- /ko -->
  976. <a class="btn dropdown-toggle" data-toggle="dropdown" href="javascript: void(0)">
  977. <span class="caret"></span>
  978. </a>
  979. <ul class="dropdown-menu">
  980. <li>
  981. <a class="pointer" rel="tooltip" data-placement="bottom" data-bind="click: function() { $root.selectedNotebook().isHidingCode(! $root.isHidingCode()); }, attr: { 'title': $root.isHidingCode() ? '${ _ko('Show the logic') }' : '${ _ko('Hide the logic') }' }">
  982. <i class="fa fa-fw" data-bind="css: { 'fa-expand': $root.isHidingCode(), 'fa-compress': ! $root.isHidingCode() }"></i>
  983. <span data-bind="visible: $root.isHidingCode">${ _('Show the code') }</span>
  984. <span data-bind="visible: ! $root.isHidingCode()">${ _('Hide the code') }</span>
  985. </a>
  986. </li>
  987. ## <li>
  988. ## <a class="pointer" data-bind="click: function() { $root.selectedNotebook().clearResults() }">
  989. ## <i class="fa fa-fw fa-eraser"></i> ${ _('Clear results') }
  990. ## </a>
  991. ## </li>
  992. <li>
  993. <a href="javascript:void(0)" data-bind="click: displayCombinedContent, visible: ! $root.isPresentationMode() ">
  994. <i class="fa fa-fw fa-file-text-o"></i> ${ _('Show all content') }
  995. </a>
  996. </li>
  997. </ul>
  998. <!-- /ko -->
  999. </div>
  1000. </script>
  1001. <script type="text/html" id="snippet-variables">
  1002. <div class="variables">
  1003. <ul data-bind="foreach: variables" class="unstyled inline">
  1004. <li>
  1005. <div class="input-prepend margin-top-10">
  1006. <!-- ko ifnot: path() -->
  1007. <span class="muted add-on" data-bind="text: name"></span>
  1008. <!-- /ko -->
  1009. <!-- ko if: path() -->
  1010. <a href="javascript:void(0);" data-bind="click: $root.showContextPopover" style="float: left"> <span class="muted add-on" data-bind="text: name"></span></a>
  1011. <!-- /ko -->
  1012. <!-- ko if: meta.type() == 'text' -->
  1013. <!-- ko if: meta.placeholder() -->
  1014. <input class="input-medium" type="text" data-bind="value: value, attr: { value: value, type: type, placeholder: meta.placeholder() || '${ _ko('Variable value') }' }, valueUpdate: 'afterkeydown', event: { 'keydown': $parent.onKeydownInVariable }, autogrowInput: { minWidth: 150, maxWidth: 270, comfortZone: 15 }">
  1015. <!-- /ko -->
  1016. <!-- ko ifnot: meta.placeholder() -->
  1017. <!-- ko if: type() == 'datetime-local' -->
  1018. <input class="input-medium" type="text" data-bind="attr: { value: value }, value: value, datepicker: { momentFormat: 'YYYY-MM-DD HH:mm:ss.S' }">
  1019. <!-- /ko -->
  1020. <!-- ko if: type() == 'date' -->
  1021. <input class="input-medium" type="text" data-bind="attr: { value: value }, value: value, datepicker: { momentFormat: 'YYYY-MM-DD' }">
  1022. <!-- /ko -->
  1023. <!-- ko if: type() == 'checkbox' -->
  1024. <input class="input-medium" type="checkbox" data-bind="checked: value">
  1025. <!-- /ko -->
  1026. <!-- ko ifnot: (type() == 'datetime-local' || type() == 'date' || type() == 'checkbox') -->
  1027. <input class="input-medium" type="text" value="true" data-bind="value: value, attr: { value: value, type: type() || 'text', step: step }, valueUpdate: 'afterkeydown', event: { 'keydown': $parent.onKeydownInVariable }, autogrowInput: { minWidth: 150, maxWidth: 270, comfortZone: 15 }">
  1028. <!-- /ko -->
  1029. <!-- /ko -->
  1030. <!-- /ko -->
  1031. <!-- ko if: meta.type() == 'select' -->
  1032. <select data-bind="selectize: sample, optionsText: 'text', optionsValue: 'value', selectizeOptions: { create: function (input) { sampleUser().push({ text: ko.observable(input), value: ko.observable(input) }); return { text: input, value: input }; } }, value: value, event: { 'keydown': $parent.onKeydownInVariable }"/>
  1033. <!-- /ko -->
  1034. </div>
  1035. </li>
  1036. </ul>
  1037. </div>
  1038. </script>
  1039. ## <script type="text/html" id="snippet-explain${ suffix }">
  1040. ## <pre class="no-margin-bottom" data-bind="text: result.explanation"></pre>
  1041. ## </script>
  1042. <script type="text/html" id="text-snippet-body${ suffix }">
  1043. <div data-bind="attr: {'id': 'editor_' + id()}, html: statement_raw, value: statement_raw, medium: {}" data-placeHolder="${ _('Type your text here, select some text to format it') }" class="text-snippet"></div>
  1044. </script>
  1045. <script type="text/html" id="markdown-snippet-body${ suffix }">
  1046. <!-- ko ifnot: $root.isPresentationMode() -->
  1047. <div class="row-fluid">
  1048. <div class="span6" data-bind="clickForAceFocus: ace">
  1049. <div class="ace-editor" data-bind="attr: { id: id() }, aceEditor: {
  1050. snippet: $data,
  1051. updateOnInput: true
  1052. }"></div>
  1053. </div>
  1054. <div class="span6">
  1055. <div data-bind="html: renderMarkdown, attr: {'id': 'liveMD' + id()}"></div>
  1056. </div>
  1057. </div>
  1058. <!-- /ko -->
  1059. <!-- ko if: $root.isPresentationMode() -->
  1060. <div data-bind="html: renderMarkdown"></div>
  1061. <!-- /ko -->
  1062. </script>
  1063. <script type="text/html" id="executable-snippet-body${ suffix }">
  1064. <div style="padding:10px;">
  1065. <form class="form-horizontal">
  1066. <!-- ko if: type() == 'distcp' -->
  1067. <div class="control-group">
  1068. <label class="control-label">${_('Source')}</label>
  1069. <div class="controls">
  1070. <input type="text" class="input-xxlarge filechooser-input" data-bind="value: properties().source_path, valueUpdate: 'afterkeydown', filechooser: properties().source_path, filechooserOptions: { linkMarkup: true, skipInitialPathIfEmpty: true, openOnFocus: true }" placeholder="${ _('Source path to copy, e.g. ${nameNode1}/path/to/input.txt') }"/>
  1071. </div>
  1072. </div>
  1073. <div class="control-group">
  1074. <label class="control-label">${_('Destination')}</label>
  1075. <div class="controls">
  1076. <input type="text" class="input-xxlarge filechooser-input" data-bind="value: properties().destination_path, valueUpdate: 'afterkeydown', filechooser: properties().destination_path, filechooserOptions: { linkMarkup: true, skipInitialPathIfEmpty: true, openOnFocus: true }" placeholder="${ _('Destination path, e.g. ${nameNode2}/path/to/output.txt') }"/>
  1077. </div>
  1078. </div>
  1079. <div class="control-group">
  1080. <label class="control-label">${_('Variables')}</label>
  1081. <div class="controls">
  1082. <!-- ko template: { if: typeof properties().distcp_parameters != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko("Arguments") }', value: properties().distcp_parameters, title: '${ _ko("Arguments for the script") }', placeholder: '${ _ko("e.g. MAX=10, PATH=$PATH:/user/path") }' } } --><!-- /ko -->
  1083. </div>
  1084. </div>
  1085. <!-- /ko -->
  1086. <!-- ko if: type() == 'shell' -->
  1087. <div class="control-group">
  1088. <label class="control-label">${_('Script path')}</label>
  1089. <div class="controls">
  1090. <input type="text" class="input-xxlarge filechooser-input" data-bind="value: properties().command_path, valueUpdate: 'afterkeydown', filechooser: properties().command_path, filechooserOptions: { linkMarkup: true, skipInitialPathIfEmpty: true, openOnFocus: true, selectFolder: false }" placeholder="${ _('Source path to the command') }"/>
  1091. </div>
  1092. </div>
  1093. <div class="control-group">
  1094. <label class="control-label">${_('Variables')}</label>
  1095. <div class="controls">
  1096. <!-- ko template: { if: typeof properties().arguments != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko("Arguments") }', value: properties().arguments, title: '${ _ko("Arguments for the script") }', placeholder: '${ _ko("e.g. MAX=10, PATH=$PATH:/user/path") }' } } --><!-- /ko -->
  1097. <!-- ko template: { if: typeof properties().env_var != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko("Environment") }', value: properties().env_var, title: '${ _ko("Environment variable for the script") }', placeholder: '${ _ko("e.g. CLASSPATH=/path/file.jar") }' } } --><!-- /ko -->
  1098. </div>
  1099. </div>
  1100. <!-- /ko -->
  1101. <!-- ko if: type() == 'mapreduce' -->
  1102. <div class="control-group">
  1103. <label class="control-label">${_('Jar path')}</label>
  1104. <div class="controls">
  1105. <input type="text" class="input-xxlarge filechooser-input" data-bind="value: properties().app_jar, valueUpdate: 'afterkeydown', filechooser: properties().app_jar, filechooserOptions: { linkMarkup: true, skipInitialPathIfEmpty: true, openOnFocus: true, selectFolder: false }" placeholder="${ _('Source path to the main MapReduce jar') }"/>
  1106. </div>
  1107. </div>
  1108. <div class="control-group">
  1109. <label class="control-label">${_('Properties')}</label>
  1110. <div class="controls">
  1111. <!-- ko template: { if: typeof properties().hadoopProperties != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko('Hadoop Properties') }', value: properties().hadoopProperties, title: '${ _ko('Name and values of Hadoop properties') }', placeholder: '${ _ko('e.g. mapred.job.queue.name=production, mapred.map.tasks.speculative.execution=false') }'}} --><!-- /ko -->
  1112. </div>
  1113. </div>
  1114. <!-- /ko -->
  1115. <!-- ko if: type() == 'jar' || type() == 'java' -->
  1116. <div class="control-group">
  1117. <label class="control-label">${_('Path')}</label>
  1118. <div class="controls">
  1119. <input type="text" class="input-xxlarge filechooser-input" data-bind="value: properties().app_jar, valueUpdate: 'afterkeydown', filechooser: properties().app_jar, filechooserOptions: { linkMarkup: true, skipInitialPathIfEmpty: true, openOnFocus: true, selectFolder: false }" placeholder="${ _('Path to application jar, e.g. hdfs://localhost:8020/user/hue/oozie-examples.jar') }"/>
  1120. </div>
  1121. </div>
  1122. <div class="control-group">
  1123. <label class="control-label">${_('Class')}</label>
  1124. <div class="controls">
  1125. <input type="text" class="input-xxlarge" data-bind="value: properties().class, valueUpdate: 'afterkeydown'" placeholder="${ _('Class name of application, e.g. org.apache.oozie.example.SparkFileCopy') }"/>
  1126. </div>
  1127. </div>
  1128. <div class="control-group">
  1129. <label class="control-label">${_('Variables')}</label>
  1130. <div class="controls">
  1131. <!-- ko template: { if: typeof properties().arguments != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko("Arguments") }', value: properties().arguments, title: '${ _ko("Arguments for the script") }', placeholder: '${ _ko("e.g. MAX=10, PATH=$PATH:/user/path") }' } } --><!-- /ko -->
  1132. </div>
  1133. </div>
  1134. <!-- /ko -->
  1135. <!-- ko if: type() == 'py'-->
  1136. <div class="control-group">
  1137. <label class="control-label">${_('Path')}</label>
  1138. <div class="controls">
  1139. <input type="text" class="input-xxlarge" data-bind="value: properties().py_file, valueUpdate: 'afterkeydown', filechooser: properties().py_file, filechooserOptions: { linkMarkup: true, skipInitialPathIfEmpty: true, openOnFocus: true, selectFolder: false }" placeholder="${ _('Path to python file, e.g. script.py') }"/>
  1140. </div>
  1141. </div>
  1142. <!-- /ko -->
  1143. <!-- ko if: type() == 'spark2' -->
  1144. <div class="control-group">
  1145. <!-- ko template: { if: typeof properties().jars != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko('Libs') }', value: properties().jars, title: '${ _ko('Path to jar or python files.') }', placeholder: '${ _ko('e.g. /user/hue/pi.py') }'}} --><!-- /ko -->
  1146. </div>
  1147. <!-- ko if: $.grep(properties().jars(), function(val, index) { return val.toLowerCase().endsWith('.jar'); }).length > 0 -->
  1148. <div class="control-group">
  1149. <label class="control-label">
  1150. ${_('Class')}
  1151. </label>
  1152. <div class="controls">
  1153. <input type="text" class="input-xxlarge" data-bind="value: properties().class, valueUpdate: 'afterkeydown'" placeholder="${ _('Class name of application, e.g. org.apache.oozie.example.SparkFileCopy') }"/>
  1154. </div>
  1155. </div>
  1156. <!-- /ko -->
  1157. <div class="control-group">
  1158. <!-- ko template: { if: typeof properties().spark_arguments != 'undefined', name: 'property', data: { type: 'csv-hdfs-files', label: '${ _ko('Arguments') }', value: properties().spark_arguments, title: '${ _ko('Arguments to the application.') }', placeholder: '${ _ko('e.g. 10, /user/hue/input') }'}} --><!-- /ko -->
  1159. </div>
  1160. <!-- /ko -->
  1161. </form>
  1162. </div>
  1163. </script>
  1164. <script type="text/html" id="snippet-execution-status${ suffix }">
  1165. <div class="snippet-execution-status" data-bind="clickForAceFocus: ace">
  1166. <a class="inactive-action pull-left snippet-logs-btn" href="javascript:void(0)" data-bind="
  1167. visible: status() === 'running' && errors().length == 0,
  1168. click: function() {
  1169. huePubSub.publish('result.grid.hide.fixed.headers');
  1170. $data.showLogs(!$data.showLogs());
  1171. },
  1172. css: {'blue': $data.showLogs}
  1173. " title="${ _('Toggle Logs') }"><i class="fa fa-fw" data-bind="css: { 'fa-caret-right': !$data.showLogs(), 'fa-caret-down': $data.showLogs() }"></i></a>
  1174. <div class="snippet-progress-container" data-bind="visible: status() != 'canceled' && status() != 'with-optimizer-report'">
  1175. <!-- ko component: { name: 'executable-progress-bar', params: { activeExecutable: activeExecutable } } --><!-- /ko -->
  1176. </div>
  1177. <div class="snippet-error-container alert alert-error" style="margin-bottom: 0" data-bind="visible: errors().length > 0">
  1178. <ul class="unstyled" data-bind="foreach: errors">
  1179. <li data-bind="text: message"></li>
  1180. <!-- ko if: help -->
  1181. <li><a href="javascript:void(0)" data-bind="click: function() {
  1182. huePubSub.publish('editor.settings.update', {
  1183. key: $data.help.setting.name,
  1184. value: $data.help.setting.value
  1185. });
  1186. $parent.settingsVisible(true);
  1187. }">${ _("Update max_row_size setting.") }</a></li>
  1188. <!-- /ko -->
  1189. </ul>
  1190. </div>
  1191. <div class="snippet-error-container alert alert-error" style="margin-bottom: 0" data-bind="visible: aceErrors().length > 0">
  1192. <ul class="unstyled" data-bind="foreach: aceErrors">
  1193. <li data-bind="text: message"></li>
  1194. </ul>
  1195. </div>
  1196. <div class="snippet-error-container alert" style="margin-bottom: 0" data-bind="visible: aceWarnings().length > 0">
  1197. <ul class="unstyled" data-bind="foreach: aceWarnings">
  1198. <li data-bind="text: message"></li>
  1199. </ul>
  1200. </div>
  1201. <div class="snippet-error-container alert alert-error" style="margin-bottom: 0" data-bind="visible: status() == 'canceled', click: function() { status('ready'); }" title="${ _('Click to hide') }">
  1202. <ul class="unstyled">
  1203. <li>${ _("The statement was canceled.") }</li>
  1204. </ul>
  1205. </div>
  1206. </div>
  1207. </script>
  1208. <script type="text/html" id="snippet-code-resizer${ suffix }">
  1209. <div class="snippet-code-resizer" data-bind="
  1210. aceResizer : {
  1211. snippet: $data,
  1212. target: '.ace-container-resizable',
  1213. onStart: function () { huePubSub.publish('result.grid.hide.fixed.headers') },
  1214. onStop: function () { huePubSub.publish('result.grid.redraw.fixed.headers') }
  1215. }">
  1216. <i class="fa fa-ellipsis-h"></i>
  1217. </div>
  1218. </script>
  1219. <script type="text/html" id="notebook-snippet-type-controls${ suffix }">
  1220. <div class="inactive-action dropdown hover-actions">
  1221. <a class="snippet-side-btn" style="padding-right: 0; padding-left: 2px;" data-toggle="dropdown" href="javascript: void(0);">
  1222. <span data-bind="template: { name: 'snippetIcon${ suffix }', data: $data }"></span>
  1223. </a>
  1224. <a class="inactive-action dropdown-toggle snippet-side-btn" style="padding:0" data-toggle="dropdown" href="javascript: void(0);">
  1225. <i class="fa fa-caret-down"></i>
  1226. </a>
  1227. <ul class="dropdown-menu" data-bind="foreach: $root.availableSnippets">
  1228. <li><a class="pointer" data-bind="click: function(){ $parent.type($data.type()); }, text: name"></a></li>
  1229. </ul>
  1230. </div>
  1231. </script>
  1232. <script type ="text/html" id="snippet-execution-controls${ suffix }">
  1233. <div class="snippet-actions clearfix">
  1234. <div class="pull-left" data-bind="component: { name: 'snippet-execute-actions', params: { activeExecutable: activeExecutable, beforeExecute: beforeExecute } }" />
  1235. <!-- ko if: isSqlDialect() && !$root.isPresentationMode() -->
  1236. <div class="pull-right" data-bind="component: { name: 'snippet-editor-actions', params: { snippet: $data } }" />
  1237. <!-- /ko -->
  1238. <div class="pull-right">
  1239. <!-- ko if: status() === 'loading' -->
  1240. <i class="fa fa-fw fa-spinner fa-spin"></i> ${ _('Creating session') }
  1241. <!-- /ko -->
  1242. ## <!-- ko if: status() !== 'loading' && $root.editorMode() && result.statements_count() > 1 -->
  1243. ## ${ _('Statement ')} <span data-bind="text: (result.statement_id() + 1) + '/' + result.statements_count()"></span>
  1244. ## <div style="display: inline-block"
  1245. ## class="label label-info"
  1246. ## data-bind="attr: {
  1247. ## 'title':'${ _ko('Showing results of the statement #')}' + (result.statement_id() + 1)}">
  1248. ## <div class="pull-left" data-bind="text: (result.statement_id() + 1)"></div><div class="pull-left">/</div><div class="pull-left" data-bind="text: result.statements_count()"></div>
  1249. ## </div>
  1250. ## <!-- /ko -->
  1251. </div>
  1252. ## TODO: Move to snippet execution-actions
  1253. ## <a class="snippet-side-btn" data-bind="click: reexecute, visible: $root.editorMode() && result.statements_count() > 1, css: {'blue': $parent.history().length == 0 || $root.editorMode(), 'disabled': ! isReady() }" title="${ _('Restart from the first statement') }">
  1254. ## <i class="fa fa-fw fa-repeat snippet-side-single"></i>
  1255. ## </a>
  1256. ## <!-- ko if: !isCanceling() -->
  1257. ## <a class="snippet-side-btn red" data-bind="click: cancel, visible: status() == 'running' || status() == 'starting'" title="${ _('Cancel operation') }">
  1258. ## <i class="fa fa-fw fa-stop snippet-side-single"></i>
  1259. ## </a>
  1260. ## <!-- /ko -->
  1261. ## <!-- ko if: isCanceling() -->
  1262. ## <a class="snippet-side-btn" style="cursor: default;" title="${ _('Canceling operation...') }">
  1263. ## <i class="fa fa-fw fa-spinner snippet-side-single fa-spin"></i>
  1264. ## </a>
  1265. ## <!-- /ko -->
  1266. ## <div style="display: inline-block" class="inactive-action dropdown hover-actions pointer" data-bind="css: {'disabled': ! isReady() || status() === 'running' || status() === 'loading' }">
  1267. ## <!-- ko if: isBatchable() && wasBatchExecuted() -->
  1268. ## <a class="snippet-side-btn" style="padding-right:0; padding-left: 2px" href="javascript: void(0)" title="${ _('Submit all the queries as a background batch job.') }" data-bind="click: function() { wasBatchExecuted(true); execute(); }, visible: status() != 'running' && status() != 'loading', css: {'blue': $parent.history().length == 0 || $root.editorMode(), 'disabled': ! isReady() }">
  1269. ## <i class="fa fa-fw fa-send"></i>
  1270. ## </a>
  1271. ## <!-- /ko -->
  1272. ## <!-- ko if: ! isBatchable() || ! wasBatchExecuted() -->
  1273. ## <a class="snippet-side-btn" style="padding-right:0" href="javascript: void(0)" data-bind="attr: {'title': $root.editorMode() && result.statements_count() > 1 ? '${ _ko('Execute next statement')}' : '${ _ko('Execute or CTRL + ENTER') }'}, click: function() { wasBatchExecuted(false); execute(); }, visible: status() != 'running' && status() != 'loading' && status() != 'starting', css: {'blue': $parent.history().length == 0 || $root.editorMode(), 'disabled': ! isReady() }, style: {'padding-left': $parent.isBatchable() ? '2px' : '0' }">
  1274. ## <i class="fa fa-fw fa-play" data-bind="css: { 'snippet-side-single' : ! $parent.isBatchable() }"></i>
  1275. ## </a>
  1276. ## <!-- /ko -->
  1277. ## % if ENABLE_BATCH_EXECUTE.get():
  1278. ## <!-- ko if: isBatchable() && status() != 'running' && status() != 'loading' && ! $root.isPresentationMode() -->
  1279. ## <a class="dropdown-toggle snippet-side-btn" style="padding:0" data-toggle="dropdown" href="javascript: void(0)" data-bind="css: {'disabled': ! isReady(), 'blue': currentQueryTab() == 'queryExplain' }">
  1280. ## <i class="fa fa-caret-down"></i>
  1281. ## </a>
  1282. ## <ul class="dropdown-menu less-padding">
  1283. ## <li>
  1284. ## <a href="javascript:void(0)" data-bind="click: function() { wasBatchExecuted(false); $('.dropdown-toggle').dropdown('toggle'); execute(); }, style: { color: ! isReady() || status() === 'running' || status() === 'loading' ? '#999' : ''}, css: {'disabled': ! isReady() || status() === 'running' || status() === 'loading' }" title="${ _('Execute interactively the current statement') }">
  1285. ## <i class="fa fa-fw fa-play"></i> ${_('Execute')}
  1286. ## </a>
  1287. ## </li>
  1288. ## <li>
  1289. ## <a href="javascript:void(0)" data-bind="click: function() { wasBatchExecuted(true); $('.dropdown-toggle').dropdown('toggle'); execute(); }, css: {'disabled': ! isReady() }" title="${ _('Submit all the queries as a background batch job.') }">
  1290. ## <i class="fa fa-fw fa-send"></i> ${_('Batch')}
  1291. ## </a>
  1292. ## </li>
  1293. ## </ul>
  1294. ## <!-- /ko -->
  1295. ## % endif
  1296. ## </div>
  1297. </div>
  1298. </script>
  1299. <div class="ace-filechooser" style="display:none;">
  1300. <div class="ace-filechooser-close">
  1301. <a class="pointer" data-bind="click: function(){ $('.ace-filechooser').hide(); }"><i class="fa fa-times"></i></a>
  1302. </div>
  1303. <div class="ace-filechooser-content">
  1304. </div>
  1305. </div>
  1306. <div id="removeSnippetModal${ suffix }" class="modal hide fade">
  1307. <div class="modal-header">
  1308. <button type="button" class="close" data-dismiss="modal" aria-label="${ _('Close') }"><span aria-hidden="true">&times;</span></button>
  1309. <h2 class="modal-title">${_('Confirm Remove')}</h2>
  1310. </div>
  1311. <div class="modal-body">
  1312. <p>${_('Are you sure you want to remove this snippet?')}</p>
  1313. </div>
  1314. <div class="modal-footer" data-bind="with: $root.removeSnippetConfirmation">
  1315. <a class="btn" data-bind="click: function() { $root.removeSnippetConfirmation(null); $('#removeSnippetModal${ suffix }').modal('hide'); }">${_('No')}</a>
  1316. <input type="submit" value="${_('Yes')}" class="btn btn-danger" data-bind="click: function() { notebook.snippets.remove(snippet); redrawFixedHeaders(100); $root.removeSnippetConfirmation(null); $('#removeSnippetModal${ suffix }').modal('hide'); }" />
  1317. </div>
  1318. </div>
  1319. <div class="hoverMsg hide">
  1320. <!-- ko if: $root.editorMode() -->
  1321. <p class="hoverText">${_('Drop a SQL file here')}</p>
  1322. <!-- /ko -->
  1323. <!-- ko ifnot: $root.editorMode() -->
  1324. <p class="hoverText">${_('Drop iPython/Zeppelin notebooks here')}</p>
  1325. <!-- /ko -->
  1326. </div>
  1327. <div id="saveAsModal${ suffix }" class="modal hide fade">
  1328. <div class="modal-header">
  1329. <button type="button" class="close" data-dismiss="modal" aria-label="${ _('Close') }"><span aria-hidden="true">&times;</span></button>
  1330. <!-- ko if: $root.editorMode() -->
  1331. <h2 class="modal-title">${_('Save query as...')}</h2>
  1332. <!-- /ko -->
  1333. <!-- ko ifnot: $root.editorMode() -->
  1334. <h2 class="modal-title">${_('Save notebook as...')}</h2>
  1335. <!-- /ko -->
  1336. </div>
  1337. <!-- ko if: $root.selectedNotebook() -->
  1338. <div class="modal-body">
  1339. <form class="form-horizontal">
  1340. <div class="control-group">
  1341. <label class="control-label">${_('Name')}</label>
  1342. <div class="controls">
  1343. <input type="text" class="input-xlarge" data-bind="value: $root.selectedNotebook().name, valueUpdate:'afterkeydown'"/>
  1344. </div>
  1345. </div>
  1346. <div class="control-group">
  1347. <label class="control-label">${_('Description')}</label>
  1348. <div class="controls">
  1349. <input type="text" class="input-xlarge" data-bind="value: $root.selectedNotebook().description, valueUpdate:'afterkeydown'" placeholder="${ _('(optional)') }"/>
  1350. </div>
  1351. </div>
  1352. </form>
  1353. </div>
  1354. <div class="modal-footer">
  1355. <a class="btn" data-dismiss="modal">${_('Cancel')}</a>
  1356. <input type="button" class="btn btn-primary disable-feedback" value="${_('Save')}" data-dismiss="modal" data-bind="click: saveAsNotebook, enable: $root.selectedNotebook().name().length > 0"/>
  1357. </div>
  1358. <!-- /ko -->
  1359. </div>
  1360. <div id="saveToFileModal${ suffix }" class="modal hide fade">
  1361. <div class="modal-header">
  1362. <button type="button" class="close" data-dismiss="modal" aria-label="${ _('Close') }"><span aria-hidden="true">&times;</span></button>
  1363. <h2 class="modal-title">${_('Are you sure you want to save back to File?')}</h2>
  1364. </div>
  1365. <div class="modal-footer">
  1366. <a class="btn" data-dismiss="modal">${_('Cancel')}</a>
  1367. <input type="button" class="btn btn-primary disable-feedback" value="${_('Save')}" data-dismiss="modal" data-bind="click: function() { huePubSub.publish('save.snippet.to.file'); }"/>
  1368. </div>
  1369. </div>
  1370. <div id="clearHistoryModal${ suffix }" class="modal hide fade">
  1371. <div class="modal-header">
  1372. <button type="button" class="close" data-dismiss="modal" aria-label="${ _('Close') }"><span aria-hidden="true">&times;</span></button>
  1373. <h2 class="modal-title">${_('Confirm History Clear')}</h2>
  1374. </div>
  1375. <div class="modal-body">
  1376. <p>${_('Are you sure you want to clear the query history?')}</p>
  1377. </div>
  1378. <div class="modal-footer">
  1379. <a class="btn" data-dismiss="modal">${_('No')}</a>
  1380. <a class="btn btn-danger disable-feedback" data-bind="click: function() { $root.selectedNotebook().clearHistory(); }">${_('Yes')}</a>
  1381. </div>
  1382. </div>
  1383. <!-- ko if: $root.selectedNotebook() -->
  1384. <!-- ko with: $root.selectedNotebook() -->
  1385. <div id="retryModal${ suffix }" class="modal hide fade" data-keyboard="false" data-backdrop="static">
  1386. <div class="modal-header">
  1387. <h2 class="modal-title">${_('Operation timed out')}</h2>
  1388. </div>
  1389. <div class="modal-body">
  1390. <p>${_('The operation timed out. Do you want to retry?')}</p>
  1391. </div>
  1392. <div class="modal-footer">
  1393. <a class="btn" data-bind="click: retryModalCancel">${_('No')}</a>
  1394. <a class="btn btn-primary disable-feedback" data-bind="click: retryModalConfirm">${_('Yes, retry')}</a>
  1395. </div>
  1396. </div>
  1397. <!-- /ko -->
  1398. <!-- /ko -->
  1399. <div class="submit-modal-editor modal hide"></div>
  1400. </%def>
  1401. <%def name="commonJS(is_embeddable=False, bindableElement='editorComponents', suffix='')">
  1402. <script type="text/javascript">
  1403. window.EDITOR_BINDABLE_ELEMENT = '#${ bindableElement }';
  1404. window.EDITOR_SUFFIX = '${ suffix }';
  1405. var HUE_PUB_SUB_EDITOR_ID = (window.location.pathname.indexOf('notebook') > -1) ? 'notebook' : 'editor';
  1406. window.EDITOR_VIEW_MODEL_OPTIONS = $.extend(${ options_json | n,unicode,antixss }, {
  1407. huePubSubId: HUE_PUB_SUB_EDITOR_ID,
  1408. user: '${ user.username }',
  1409. userId: ${ user.id },
  1410. suffix: '${ suffix }',
  1411. assistAvailable: true,
  1412. autocompleteTimeout: AUTOCOMPLETE_TIMEOUT,
  1413. snippetViewSettings: {
  1414. default: {
  1415. placeHolder: '${ _("Example: SELECT * FROM tablename, or press CTRL + space") }',
  1416. aceMode: 'ace/mode/sql',
  1417. snippetIcon: 'fa-database',
  1418. sqlDialect: true
  1419. },
  1420. code: {
  1421. placeHolder: '${ _("Example: 1 + 1, or press CTRL + space") }',
  1422. snippetIcon: 'fa-code'
  1423. },
  1424. hive: {
  1425. placeHolder: '${ _("Example: SELECT * FROM tablename, or press CTRL + space") }',
  1426. aceMode: 'ace/mode/hive',
  1427. snippetImage: '${ static("beeswax/art/icon_beeswax_48.png") }',
  1428. sqlDialect: true
  1429. },
  1430. impala: {
  1431. placeHolder: '${ _("Example: SELECT * FROM tablename, or press CTRL + space") }',
  1432. aceMode: 'ace/mode/impala',
  1433. snippetImage: '${ static("impala/art/icon_impala_48.png") }',
  1434. sqlDialect: true
  1435. },
  1436. jar : {
  1437. snippetIcon: 'fa-file-archive-o '
  1438. },
  1439. mysql: {
  1440. placeHolder: '${ _("Example: SELECT * FROM tablename, or press CTRL + space") }',
  1441. aceMode: 'ace/mode/mysql',
  1442. snippetIcon: 'fa-database',
  1443. sqlDialect: true
  1444. },
  1445. mysqljdbc: {
  1446. placeHolder: '${ _("Example: SELECT * FROM tablename, or press CTRL + space") }',
  1447. aceMode: 'ace/mode/mysql',
  1448. snippetIcon: 'fa-database',
  1449. sqlDialect: true
  1450. },
  1451. oracle: {
  1452. placeHolder: '${ _("Example: SELECT * FROM tablename, or press CTRL + space") }',
  1453. aceMode: 'ace/mode/oracle',
  1454. snippetIcon: 'fa-database',
  1455. sqlDialect: true
  1456. },
  1457. pig: {
  1458. placeHolder: '${ _("Example: 1 + 1, or press CTRL + space") }',
  1459. aceMode: 'ace/mode/pig',
  1460. snippetImage: '${ static("pig/art/icon_pig_48.png") }'
  1461. },
  1462. postgresql: {
  1463. placeHolder: '${ _("Example: SELECT * FROM tablename, or press CTRL + space") }',
  1464. aceMode: 'ace/mode/pgsql',
  1465. snippetIcon: 'fa-database',
  1466. sqlDialect: true
  1467. },
  1468. solr: {
  1469. placeHolder: '${ _("Example: SELECT fieldA, FieldB FROM collectionname, or press CTRL + space") }',
  1470. aceMode: 'ace/mode/mysql',
  1471. snippetIcon: 'fa-database',
  1472. sqlDialect: true
  1473. },
  1474. kafkasql: {
  1475. placeHolder: '${ _("Example: SELECT fieldA, FieldB FROM collectionname, or press CTRL + space") }',
  1476. aceMode: 'ace/mode/mysql',
  1477. snippetIcon: 'fa-database',
  1478. sqlDialect: true
  1479. },
  1480. java : {
  1481. snippetIcon: 'fa-file-code-o'
  1482. },
  1483. py : {
  1484. snippetIcon: 'fa-file-code-o'
  1485. },
  1486. pyspark: {
  1487. placeHolder: '${ _("Example: 1 + 1, or press CTRL + space") }',
  1488. aceMode: 'ace/mode/python',
  1489. snippetImage: '${ static("spark/art/icon_spark_48.png") }'
  1490. },
  1491. r: {
  1492. placeHolder: '${ _("Example: 1 + 1, or press CTRL + space") }',
  1493. aceMode: 'ace/mode/r',
  1494. snippetImage: '${ static("spark/art/icon_spark_48.png") }'
  1495. },
  1496. scala: {
  1497. placeHolder: '${ _("Example: 1 + 1, or press CTRL + space") }',
  1498. aceMode: 'ace/mode/scala',
  1499. snippetImage: '${ static("spark/art/icon_spark_48.png") }'
  1500. },
  1501. spark: {
  1502. placeHolder: '${ _("Example: 1 + 1, or press CTRL + space") }',
  1503. aceMode: 'ace/mode/scala',
  1504. snippetImage: '${ static("spark/art/icon_spark_48.png") }'
  1505. },
  1506. spark2: {
  1507. snippetImage: '${ static("spark/art/icon_spark_48.png") }'
  1508. },
  1509. mapreduce: {
  1510. snippetIcon: 'fa-file-archive-o'
  1511. },
  1512. shell: {
  1513. snippetIcon: 'fa-terminal'
  1514. },
  1515. sqoop1: {
  1516. placeHolder: '${ _("Example: import --connect jdbc:hsqldb:file:db.hsqldb --table TT --target-dir hdfs://localhost:8020/user/foo -m 1") }',
  1517. snippetImage: '${ static("sqoop/art/icon_sqoop_48.png") }'
  1518. },
  1519. distcp: {
  1520. snippetIcon: 'fa-files-o'
  1521. },
  1522. sqlite: {
  1523. placeHolder: '${ _("Example: SELECT * FROM tablename, or press CTRL + space") }',
  1524. aceMode: 'ace/mode/sql',
  1525. snippetIcon: 'fa-database',
  1526. sqlDialect: true
  1527. },
  1528. text: {
  1529. placeHolder: '${ _('Type your text here') }',
  1530. aceMode: 'ace/mode/text',
  1531. snippetIcon: 'fa-header'
  1532. },
  1533. markdown: {
  1534. placeHolder: '${ _('Type your markdown here') }',
  1535. aceMode: 'ace/mode/markdown',
  1536. snippetIcon: 'fa-header'
  1537. }
  1538. }
  1539. });
  1540. window.EDITOR_ENABLE_QUERY_SCHEDULING = '${ ENABLE_QUERY_SCHEDULING.get() }' === 'True';
  1541. window.EDITOR_ID = ${ editor_id or 'null' };
  1542. window.NOTEBOOKS_JSON = ${ notebooks_json | n,unicode };
  1543. window.OPTIMIZER_AUTO_UPLOAD_QUERIES = '${ OPTIMIZER.AUTO_UPLOAD_QUERIES.get() }' === 'True';
  1544. window.OPTIMIZER_AUTO_UPLOAD_DDL = '${ OPTIMIZER.AUTO_UPLOAD_DDL.get() }' === 'True';
  1545. window.OPTIMIZER_QUERY_HISTORY_UPLOAD_LIMIT = ${ OPTIMIZER.QUERY_HISTORY_UPLOAD_LIMIT.get() };
  1546. </script>
  1547. </%def>