hive.mako 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. ## Licensed to Cloudera, Inc. under one
  2. ## or more contributor license agreements. See the NOTICE file
  3. ## distributed with this work for additional information
  4. ## regarding copyright ownership. Cloudera, Inc. licenses this file
  5. ## to you under the Apache License, Version 2.0 (the
  6. ## "License"); you may not use this file except in compliance
  7. ## with the License. You may obtain a copy of the License at
  8. ##
  9. ## http://www.apache.org/licenses/LICENSE-2.0
  10. ##
  11. ## Unless required by applicable law or agreed to in writing, software
  12. ## distributed under the License is distributed on an "AS IS" BASIS,
  13. ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ## See the License for the specific language governing permissions and
  15. ## limitations under the License.
  16. <%!
  17. from desktop.views import commonheader, commonfooter
  18. from django.utils.translation import ugettext as _
  19. %>
  20. <%namespace name="actionbar" file="actionbar.mako" />
  21. <%namespace name="layout" file="layout.mako" />
  22. <%namespace name="tree" file="common_tree.mako" />
  23. ${ commonheader(_('Hadoop Security'), "security", user) | n,unicode }
  24. ${ layout.menubar(section='hive') }
  25. <script type="text/html" id="role">
  26. <div class="acl-block-title"><i class="fa fa-cube muted"></i> <a class="pointer" data-bind="click: function(){ $root.showRole($data); }"><span data-bind="text: name"></span></a></div>
  27. <div data-bind="template: { name: 'privilege', foreach: privileges }"></div>
  28. <div class="acl-block acl-actions" data-bind="click: privilegesChanged().length == 0 ? addPrivilege : void(0)">
  29. <span class="pointer" data-bind="click: addPrivilege" title="${ _('Add privilege') }"><i class="fa fa-plus"></i></span>
  30. <span class="pointer" data-bind="click: $root.list_sentry_privileges_by_authorizable, visible: privilegesChanged().length > 0" title="${ _('Undo') }"> &nbsp; <i class="fa fa-undo"></i></span>
  31. <span class="pointer" data-bind="click: $root.role.savePrivileges, visible: privilegesChanged().length > 0" title="${ _('Save') }"> &nbsp; <i class="fa fa-save"></i></span>
  32. </div>
  33. </script>
  34. <script type="text/html" id="privilege">
  35. <div data-bind="visible: status() != 'deleted' && status() != 'alreadydeleted'" class="acl-block acl-block-airy">
  36. <!-- ko if: editing() -->
  37. <div class="pull-right">
  38. <a class="pointer" style="margin-right: 4px" data-bind="click: function() { if (editing()) { editing(false); }}"><i class="fa fa-eye"></i></a>
  39. <a class="pointer" style="margin-right: 4px" data-bind="click: remove"><i class="fa fa-times"></i></a>
  40. </div>
  41. <input value="db" data-bind="attr: { name: 'privilege-' + $index() }, checked: type" type="radio" />
  42. <input type="text" data-bind="hivechooser: $data.path, enable: type() == 'db'" placeholder="dbName.tableName">
  43. <input value="uri" data-bind="attr: { name: 'privilege-' + $index() }, checked: type" type="radio"/>
  44. <input type="text" data-bind="filechooser: $data.URI, enable: type() == 'uri'" placeholder="URI">
  45. <select data-bind="options: $root.availableActions, select2: { update: $data.action, type: 'action'}" style="width: 100px"></select>
  46. <span class="showAdvancedSpace">&nbsp;&nbsp;</span><a class="pointer showAdvanced" data-bind="click: function(){ showAdvanced(true); }, visible: ! showAdvanced()"><i class="fa fa-cog"></i> ${ _('Show advanced') }</a>
  47. <div class="acl-block-section" data-bind="visible: showAdvanced">
  48. <input type="text" data-bind="value: serverName" placeholder="serverName">
  49. <select data-bind="options: $root.availablePrivileges, select2: { update: $data.privilegeScope, type: 'scope'}" style="width: 100px"></select>
  50. </div>
  51. <!-- /ko -->
  52. <!-- ko ifnot: editing() -->
  53. <div class="pull-right">
  54. <a class="pointer" style="margin-right: 4px" data-bind="click: function() { if (! editing()) { editing(true); }}"><i class="fa fa-pencil"></i></a>
  55. <a class="pointer" style="margin-right: 4px" data-bind="click: remove"><i class="fa fa-times"></i></a>
  56. </div>
  57. <em class="muted" data-bind="text: moment(timestamp()).fromNow()"></em> <span class="muted" data-bind="text: privilegeScope"></span><br/>
  58. server=<span data-bind="text: serverName"></span>
  59. <!-- ko ifnot: URI() -->
  60. <span data-bind="visible: dbName">
  61. <i class="fa fa-long-arrow-right"></i> db=<a data-bind="attr: { href: '/metastore/tables/' + dbName() }" target="_blank"><span data-bind="text: dbName"></span></a>
  62. </span>
  63. <span data-bind="visible: tableName">
  64. <i class="fa fa-long-arrow-right"></i> table=<a data-bind="attr: { href: '/metastore/table/' + dbName() + '/' + tableName() }" target="_blank"><span data-bind="text: tableName"></span></a>
  65. </span>
  66. <i class="fa fa-long-arrow-right"></i> action=<span data-bind="text: action"></span>
  67. <!-- /ko -->
  68. <!-- ko if: URI() -->
  69. <span data-bind="text: URI"></span>
  70. <!-- /ko -->
  71. <br/>
  72. <span data-bind="text: grantor"></span>
  73. <!-- /ko -->
  74. </div>
  75. </script>
  76. <div class="container-fluid">
  77. <div class="row-fluid">
  78. <div class="span2">
  79. <div class="sidebar-nav">
  80. <ul class="nav nav-list">
  81. <li class="nav-header">${ _('Privileges') }</li>
  82. <li class="active"><a href="javascript:void(0)" data-toggleSection="edit"><i class="fa fa-sitemap fa-rotate-270"></i> ${ _('Browse') }</a></li>
  83. <li><a href="javascript:void(0)" data-toggleSection="roles"><i class="fa fa-cubes"></i> ${ _('Roles') }</a></li>
  84. <li class="nav-header"><i class="fa fa-group"></i> ${ _('Groups') }
  85. <div>
  86. <br/>
  87. <select id="selectedGroup" data-bind="options: $root.selectableHadoopGroups, select2: { update: $data.action, type: 'action', allowClear: true }" style="width: 100%"></select>
  88. </div>
  89. </li>
  90. </ul>
  91. </div>
  92. </div>
  93. <div class="span10">
  94. <div id="edit" class="mainSection card card-small">
  95. <h1 class="card-heading simple">
  96. ${ _('Database and Tables privileges') }
  97. </h1>
  98. <div class="card-body">
  99. <div class="row-fluid">
  100. <div class="span6">
  101. <div class="path-container">
  102. <div class="input-append span12">
  103. <input id="path" class="path" type="text" autocomplete="off" />
  104. <a data-bind="attr: { href: '/metastore/' + $root.assist.path() }" target="_blank" title="${ _('Open in Metastore Browser') }" class="btn btn-inverse">
  105. <i class="fa fa-external-link"></i>
  106. </a>
  107. </div>
  108. <div class="clearfix"></div>
  109. <div class="tree-toolbar">
  110. <div class="pull-right">
  111. <div class="dropdown inline-block" style="margin-right: 6px">
  112. <a class="dropdown-toggle" data-toggle="dropdown" href="#">
  113. <i class="fa fa-eye-slash" data-bind="visible: $root.assist.isDiffMode"></i>
  114. <i class="fa fa-eye" data-bind="visible: ! $root.assist.isDiffMode()"></i>
  115. <span data-bind="visible: $root.assist.isDiffMode">${ _('Show non accessible paths for') }</span>
  116. <span data-bind="visible: ! $root.assist.isDiffMode()">${ _('Impersonate the user') }</span>
  117. </a>
  118. <ul class="dropdown-menu">
  119. <li data-bind="visible: ! $root.assist.isDiffMode(), click: function() { $root.assist.isDiffMode(true); }">
  120. <a tabindex="-1" href="#">${ _('Show non accessible paths for') }</a>
  121. </li>
  122. <li data-bind="visible: $root.assist.isDiffMode(), click: function() { $root.assist.isDiffMode(false); }">
  123. <a tabindex="-1" href="#">${ _('Impersonate the user') }</a>
  124. </li>
  125. </ul>
  126. </div>
  127. <select class="user-list" data-bind="options: $root.selectableHadoopUsers, select2: { placeholder: '${ _("Select a user") }', update: $root.doAs, type: 'user'}" style="width: 120px"></select>
  128. <i class="fa fa-group" title="${ _('List of groups in popover for this user?') }"></i>
  129. </div>
  130. <div>
  131. <i class="fa fa-spinner fa-spin" data-bind="visible: $root.assist.isLoadingTree()"></i>
  132. <a class="pointer" data-bind="click: $root.assist.collapseOthers" rel="tooltip" data-placement="right" title="${_('Close other nodes')}">
  133. <i class="fa fa-compress"></i>
  134. </a>
  135. &nbsp;
  136. <a class="pointer" data-bind="click: $root.assist.refreshTree" rel="tooltip" data-placement="right" title="${_('Refresh the tree')}">
  137. <i class="fa fa-refresh"></i>
  138. </a>
  139. &nbsp;
  140. <a class="pointer" data-bind="visible: $root.assist.checkedItems().length > 0, click: function(){ $('#bulkActionsModal').modal('show'); }" rel="tooltip" data-placement="right" title="${ _('Add, replace or remove ACLs for the checked paths') }">
  141. <i class="fa fa-copy"></i>
  142. </a>
  143. </div>
  144. </div>
  145. </div>
  146. ${ tree.render(id='expandableTree', data='$root.assist.treeData', afterRender='$root.assist.afterRender') }
  147. </div>
  148. <div class="span6 acl-panel">
  149. <div class="acl-panel-content">
  150. <h4 style="margin-top: 4px">${ _('Privileges') }</h4>
  151. <div data-bind="visible: $root.assist.privileges().length == 0"><em class="muted">${ _('No privileges found for the selected item.')} <a class="pointer" data-bind="click: function(){ $root.showCreateRole(true); $('#createRoleModal').modal('show'); }">${ _('Click here to add a new role.') }</a> </em></div>
  152. <div data-bind="template: { name: 'role', foreach: $root.assist.roles }"></div>
  153. </div>
  154. </div>
  155. </div>
  156. </div>
  157. </div>
  158. <div id="roles" class="mainSection hide card card-small">
  159. <h1 class="card-heading simple">
  160. ${ _('Roles') }
  161. </h1>
  162. <div class="card-body">
  163. <div class="span10 offset1 center" style="cursor: pointer" data-bind="visible: $root.roles().length == 0, click: function(){ $root.showCreateRole(true); $('#createRoleModal').modal('show'); }">
  164. <i class="fa fa-plus-circle waiting"></i>
  165. <h1 class="emptyMessage">${ _('There are currently no roles defined.') }<br/><a class="pointer">${ _('Click here to add') }</a> ${ _('one.') }</h1>
  166. </div>
  167. <div class="clearfix" data-bind="visible: $root.roles().length == 0"></div>
  168. <div data-bind="visible: $root.roles().length > 0">
  169. <%actionbar:render>
  170. <%def name="search()">
  171. <input id="filterInput" type="text" class="input-xlarge search-query" placeholder="${_('Search for name, groups, etc...')}" data-bind="value: $root.roleFilter, valueUpdate: 'afterkeydown'">
  172. </%def>
  173. <%def name="actions()">
  174. <button class="btn toolbarBtn" data-bind="click: $root.expandSelectedRoles, enable: $root.selectedRoles().length > 0"><i class="fa fa-expand"></i> ${ _('Expand') }</button>
  175. <button class="btn toolbarBtn" data-bind="click: function(){ $('#deleteRoleModal').modal('show'); }, enable: $root.selectedRoles().length > 0"><i class="fa fa-times"></i> ${ _('Delete') }</button>
  176. </%def>
  177. <%def name="creation()">
  178. <a data-bind="click: function(){ $root.showCreateRole(true); $('#createRoleModal').modal('show'); }" class="btn pointer"><i class="fa fa-plus-circle"></i> ${ _('Add') }</a>
  179. </%def>
  180. </%actionbar:render>
  181. </div>
  182. <table class="card-marginbottom" data-bind="visible: $root.roles().length > 0">
  183. <thead>
  184. <th width="1%"><div data-bind="click: $root.selectAllRoles, css: { hueCheckbox: true, 'fa': true, 'fa-check': allRolesSelected }"></div></th>
  185. <th width="2%"></th>
  186. <th width="20%">${ _('Name') }</th>
  187. <th width="54%">${ _('Groups') }</th>
  188. <th width="20%">${ _('Grantor Principal') }</th>
  189. <th width="3%"></th>
  190. </thead>
  191. <tbody data-bind="foreach: $root.filteredRoles">
  192. <tr>
  193. <td class="center" data-bind="click: handleSelect" style="cursor: default">
  194. <div data-bind="css: { hueCheckbox: true, 'fa': true, 'fa-check': selected }"></div>
  195. </td>
  196. <td class="center">
  197. <a href="javascript:void(0);" title="${ _('Show privileges') }">
  198. <i class="fa fa-2x fa-caret" data-bind="click: function() { if (showPrivileges()) { showPrivileges(false); } else { $root.list_sentry_privileges_by_role($data);} }, css: {'fa-caret-right' : ! showPrivileges(), 'fa-caret-down': showPrivileges() }"></i>
  199. </a>
  200. </td>
  201. <td>
  202. <a data-bind="attr: {'href': name}"></a>
  203. <i class="fa fa-cube muted"></i>
  204. <span data-bind="text: name, click: function() { if (showPrivileges()) { showPrivileges(false); } else { $root.list_sentry_privileges_by_role($data);} }" class="pointer"/>
  205. </td>
  206. <td>
  207. <a class="pointer" data-bind="click: function() { showEditGroups(true); }">
  208. <span data-bind="foreach: groups, visible: ! showEditGroups() && ! groupsChanged()">
  209. <span data-bind="text: $data"></span>
  210. </span>
  211. <span data-bind="visible: ! showEditGroups() && ! groupsChanged() && groups().length == 0">
  212. <i class="fa fa-plus"></i> ${ _('Add a group') }
  213. </span>
  214. </a>
  215. <div data-bind="visible: showEditGroups() || groupsChanged()">
  216. <select data-bind="options: $root.selectableHadoopGroups, selectedOptions: groups, select2: { update: groups, type: 'group'}" size="5" multiple="true" style="width: 400px"></select>
  217. <a class="pointer" data-bind="visible: groupsChanged, click: resetGroups">
  218. <i class="fa fa-undo"></i>
  219. </a>
  220. <a class="pointer" data-bind="visible: groupsChanged, click: saveGroups">
  221. <i class="fa fa-save"></i>
  222. </a>
  223. </div>
  224. </td>
  225. <td>
  226. <a href=""><span data-bind="text: grantorPrincipal"></span></a>
  227. </td>
  228. <td>
  229. </td>
  230. </tr>
  231. <tr>
  232. <td colspan="2"></td>
  233. <td colspan="4">
  234. <div data-bind="template: { name: 'privilege', foreach: $data.privileges }, visible: $data.showPrivileges">
  235. </div>
  236. </td>
  237. </tr>
  238. <tr data-bind="visible: $data.showPrivileges">
  239. <td colspan="2"></td>
  240. <td colspan="4">
  241. <div class="acl-block acl-actions" data-bind="click: privilegesChanged().length == 0 ? addPrivilege : void(0)">
  242. <span class="pointer" data-bind="click: addPrivilege, visible: $data.showPrivileges" title="${ _('Add privilege') }"><i class="fa fa-plus"></i></span>
  243. <span class="pointer" data-bind="click: $root.list_sentry_privileges_by_role, visible: privilegesChanged().length > 0" title="${ _('Undo') }"> &nbsp; <i class="fa fa-undo"></i></span>
  244. <span class="pointer" data-bind="click: $root.role.savePrivileges, visible: privilegesChanged().length > 0" title="${ _('Save') }"> &nbsp; <i class="fa fa-save"></i></span>
  245. </div>
  246. </td>
  247. </tr>
  248. </tbody>
  249. </table>
  250. </div>
  251. </div>
  252. </div> <!-- /span10 -->
  253. </div>
  254. <div id="createRoleModal" class="modal hide fade in" role="dialog">
  255. <div class="modal-header">
  256. <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
  257. <h3>${ _('Add role') }</h3>
  258. </div>
  259. <div class="modal-body" data-bind="with: $root.role, visible: showCreateRole">
  260. <div class="row-fluid">
  261. <div class="span6">
  262. <h4>${ _('Name') }</h4>
  263. <input type="text" class="input-xlarge" data-bind="value: $data.name" placeholder="${ _('Required') }" style="width: 360px" />
  264. </div>
  265. <div class="span6">
  266. <h4>${ _('Groups') }</h4>
  267. <select data-bind="options: $root.selectableHadoopGroups, selectedOptions: groups, select2: { update: groups, type: 'group', placeholder: '${ _("Optional") }' }" size="5" multiple="true" style="width: 360px"></select>
  268. </div>
  269. </div>
  270. <h4>${ _('Privileges') }</h4>
  271. <div data-bind="template: { name: 'privilege', foreach: privileges }"></div>
  272. <div class="acl-block acl-actions pointer" data-bind="click: addPrivilege">
  273. <span class="pointer" title="${ _('Add privilege') }"><i class="fa fa-plus"></i></span>
  274. </div>
  275. </div>
  276. <div class="modal-footer">
  277. <button class="btn" data-dismiss="modal" aria-hidden="true" data-bind="click: $root.role.reset">${ _('Cancel') }</button>
  278. <button data-loading-text="${ _('Saving...') }" class="btn btn-primary disable-enter" data-bind="click: $root.role.create">${ _('Save') }</button>
  279. </div>
  280. </div>
  281. <div id="deleteRoleModal" class="modal hide fade in" role="dialog">
  282. <div class="modal-header">
  283. <a href="#" class="close" data-dismiss="modal">&times;</a>
  284. <h3>${ _('Do you really want to delete the selected role(s)?') }</h3>
  285. </div>
  286. <div class="modal-footer">
  287. <button class="btn" data-dismiss="modal" aria-hidden="true">${ _('Cancel') }</button>
  288. <button data-loading-text="${ _('Deleting...') }" class="btn btn-danger" data-bind="click: $root.deleteSelectedRoles">${ _('Yes') }</button>
  289. </div>
  290. </div>
  291. <div id="bulkActionsModal" class="modal hide fade in" role="dialog">
  292. <div class="modal-header">
  293. <a href="#" class="close" data-dismiss="modal">&times;</a>
  294. <h3>${ _('Apply some bulk operations') }</h3>
  295. </div>
  296. <div class="modal-body" style="overflow-x: hidden">
  297. <div class="row-fluid">
  298. <div class="span6">
  299. <h4>${ _('Checked items') }</h4>
  300. <ul class="unstyled modal-panel" data-bind="foreach: $root.assist.checkedItems">
  301. <li><span class="force-word-break" data-bind="text: path"></span></li>
  302. </ul>
  303. </div>
  304. <div class="span6">
  305. <h4>${ _('Selected item for privilege actions') }</h4>
  306. <div data-bind="visible: $root.assist.privileges().length == 0"><em class="muted">${ _('No privileges found for the selected item.')}</em></div>
  307. <div data-bind="template: { name: 'role', foreach: $root.assist.roles }" class="modal-panel"></div>
  308. </div>
  309. </div>
  310. <h4>${ _('Choose your action') }</h4>
  311. <div class="row-fluid">
  312. <div class="span4 center">
  313. <div class="big-btn" data-bind="css: {'selected': $root.bulkAction() == 'add'}, click: function(){$root.bulkAction('add')}">
  314. <i class="fa fa-plus"></i><br/><br/>
  315. <span class="bulk-action-description">${ _('Add current privileges to checkbox selection') }</span>
  316. </div>
  317. </div>
  318. <div class="span4 center">
  319. <div class="big-btn" data-bind="css: {'selected': $root.bulkAction() == 'sync'}, click: function(){$root.bulkAction('sync')}">
  320. <i class="fa fa-eraser"></i><br/><br/>
  321. <span class="bulk-action-description">${ _('Replace checkbox selection with current privileges') }</span>
  322. </div>
  323. </div>
  324. <div class="span4 center">
  325. <div class="big-btn" data-bind="css: {'selected': $root.bulkAction() == 'delete'}, click: function(){$root.bulkAction('delete')}">
  326. <i class="fa fa-times"></i><br/><br/>
  327. <span class="bulk-action-description">${ _('Remove privileges of checkbox selection') }</span>
  328. </div>
  329. </div>
  330. </div>
  331. </div>
  332. <div class="modal-footer">
  333. <button class="btn" data-dismiss="modal" aria-hidden="true">${ _('Cancel') }</button>
  334. <button class="btn" data-bind="css: {'btn-primary': $root.bulkAction() != 'delete', 'btn-danger': $root.bulkAction() == 'delete'}, click: $root.bulkPerfomAction">${ _('Confirm') }</button>
  335. </div>
  336. </div>
  337. <div id="chooseFile" class="modal hide fade">
  338. <div class="modal-header">
  339. <a href="#" class="close" data-dismiss="modal">&times;</a>
  340. <h3>${_('Choose a file')}</h3>
  341. </div>
  342. <div class="modal-body">
  343. <div id="filechooser">
  344. </div>
  345. </div>
  346. <div class="modal-footer">
  347. </div>
  348. </div>
  349. <%def name="treeIcons()">
  350. 'fa-database': isDb(),
  351. 'fa-table': isTable(),
  352. 'fa-columns': isColumn()
  353. </%def>
  354. ${ tree.import_templates(itemClick='$root.assist.setPath', iconClick='$root.assist.togglePath', itemSelected='$root.assist.path() == path()', iconModifier=treeIcons, anchorProperty='path', itemChecked='isChecked') }
  355. <script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
  356. <script src="/static/ext/js/knockout.mapping-2.3.2.js" type="text/javascript" charset="utf-8"></script>
  357. <script src="/static/ext/js/routie-0.3.0.min.js" type="text/javascript" charset="utf-8"></script>
  358. <script src="/security/static/js/common.ko.js" type="text/javascript" charset="utf-8"></script>
  359. <script src="/security/static/js/hive.ko.js" type="text/javascript" charset="utf-8"></script>
  360. <script src="/static/ext/js/moment.min.js" type="text/javascript" charset="utf-8"></script>
  361. <script src="/static/js/jquery.hiveautocomplete.js" type="text/javascript" charset="utf-8"></script>
  362. <script src="/static/js/jquery.filechooser.js" type="text/javascript" charset="utf-8"></script>
  363. <script type="text/javascript" charset="utf-8">
  364. var viewModel = new HiveViewModel(${ initial | n,unicode });
  365. ko.applyBindings(viewModel);
  366. $(document).ready(function () {
  367. var _initialPath = viewModel.getPathHash();
  368. viewModel.init(_initialPath);
  369. $("#path").val(_initialPath);
  370. function setPathFromAutocomplete(path){
  371. if (path.lastIndexOf(".") == path.length -1){
  372. path = path.substring(0, path.length - 1);
  373. }
  374. viewModel.assist.path(path);
  375. viewModel.assist.updatePathProperty(viewModel.assist.growingTree(), path, "isExpanded", true);
  376. viewModel.assist.fetchHivePath();
  377. }
  378. $("#path").jHueHiveAutocomplete({
  379. skipColumns: true,
  380. home: viewModel.assist.path(),
  381. onPathChange: function (path) {
  382. setPathFromAutocomplete(path);
  383. },
  384. onEnter: function (el) {
  385. setPathFromAutocomplete(el.val());
  386. },
  387. smartTooltip: "${_('Did you know? You can use the tab key or CTRL + Space to autocomplete file and folder names')}"
  388. });
  389. function resizeComponents() {
  390. $("#path").width($(".tree-toolbar").width() - 64);
  391. $("#expandableTree").height($(window).height() - 260);
  392. $(".acl-panel-content").height($(window).height() - 240);
  393. }
  394. resizeComponents();
  395. $(document).on("rendered.tree", function() {
  396. var _path = viewModel.assist.path();
  397. if (_path[_path.length-1] == "/"){
  398. _path = _path.substr(0, _path.length - 1);
  399. }
  400. if ($("a.anchor[href^='"+_path+"']").length > 0){
  401. $("#expandableTree").animate({
  402. scrollTop: ($("a.anchor[href^='"+_path+"']:first").position().top + $("#expandableTree").scrollTop() - $("#expandableTree").position().top - 4)+"px"
  403. });
  404. }
  405. });
  406. $(document).on("created.role", function(){
  407. $("#createRoleModal").modal("hide");
  408. });
  409. $(document).on("deleted.role", function(){
  410. $("#deleteRoleModal").modal("hide");
  411. });
  412. $(document).on("changed.path", function(){
  413. if ($("#path").val() != viewModel.assist.path()){
  414. $("#path").val(viewModel.assist.path());
  415. }
  416. });
  417. function showMainSection(mainSection) {
  418. if ($("#" + mainSection).is(":hidden")) {
  419. $(".mainSection").hide();
  420. $("#" + mainSection).show();
  421. highlightMainMenu(mainSection);
  422. viewModel.updateSectionHash(mainSection);
  423. }
  424. logGA(mainSection);
  425. }
  426. function highlightMainMenu(mainSection) {
  427. $(".nav.nav-list li").removeClass("active");
  428. $("a[data-toggleSection='" + mainSection + "']").parent().addClass("active");
  429. }
  430. $("[data-toggleSection]").on("click", function(){
  431. showMainSection($(this).attr("data-toggleSection"));
  432. });
  433. showMainSection(viewModel.getSectionHash());
  434. $(document).on("show.role", function(e, role) {
  435. if (typeof role != "undefined" && role.name != null){
  436. $("#bulkActionsModal").modal("hide");
  437. showMainSection("roles");
  438. $("html, body").animate({
  439. scrollTop: ($("a[href='" + role.name() + "']").position().top - 90)+"px"
  440. });
  441. }
  442. });
  443. var _resizeTimeout = -1;
  444. $(window).resize(function(){
  445. window.clearTimeout(_resizeTimeout);
  446. _resizeTimeout = window.setTimeout(resizeComponents, 100);
  447. });
  448. window.onpopstate = function() {
  449. viewModel.assist.path(viewModel.getPathHash());
  450. };
  451. $("#createRoleModal").modal({
  452. show: false
  453. });
  454. $("#deleteRoleModal").modal({
  455. show: false
  456. });
  457. $("#selectedGroup").select2("val", "");
  458. $("#selectedGroup").change(function() {
  459. viewModel.list_sentry_privileges_by_authorizable();
  460. viewModel.list_sentry_roles_by_group();
  461. });
  462. $(document).on("added.bulk.privileges", function() {
  463. $(document).trigger("info", "${ _('The current privileges have been successfully added to the checked items.') }");
  464. $("#bulkActionsModal").modal("hide");
  465. });
  466. $(document).on("deleted.bulk.privileges", function() {
  467. $(document).trigger("info", "${ _('All the privileges have been successfully removed from the checked items.') }");
  468. $("#bulkActionsModal").modal("hide");
  469. });
  470. $(document).on("syncd.bulk.privileges", function() {
  471. $(document).trigger("info", "${ _('All the privileges for the checked items have been replaced with the current selection.') }");
  472. $("#bulkActionsModal").modal("hide");
  473. });
  474. $("#bulkActionsModal").modal({
  475. show: false
  476. });
  477. });
  478. </script>
  479. ${ commonfooter(messages) | n,unicode }