conjur-asset-ui 1.4.2 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -3
  3. data/CHANGELOG.md +10 -0
  4. data/Makefile +19 -0
  5. data/README.md +0 -3
  6. data/Rakefile +22 -17
  7. data/TODO.md +0 -23
  8. data/app/.csscomb.json +304 -0
  9. data/app/.eslintignore +3 -0
  10. data/app/.eslintrc +265 -0
  11. data/app/config/preprocessor.js +19 -0
  12. data/app/config/webpack.js +124 -0
  13. data/app/gulpfile.js +96 -0
  14. data/app/package.json +86 -0
  15. data/app/src/actions.js +550 -0
  16. data/app/src/app.js +83 -0
  17. data/app/src/clients/audit.js +34 -0
  18. data/app/src/clients/auth.js +24 -0
  19. data/app/src/clients/generic.js +52 -0
  20. data/app/src/clients/graph.js +7 -0
  21. data/app/src/clients/layer_members.js +18 -0
  22. data/app/src/clients/list.js +31 -0
  23. data/app/src/clients/members.js +20 -0
  24. data/app/src/clients/request.js +531 -0
  25. data/app/src/clients/search.js +5 -0
  26. data/app/src/components/app/__tests__/app-test.js +22 -0
  27. data/app/src/components/app/app.js +36 -0
  28. data/app/src/components/app/wrapper.js +17 -0
  29. data/app/src/components/audit/__tests__/table_header-test.js +22 -0
  30. data/app/src/components/audit/box.js +9 -0
  31. data/app/src/components/audit/constants.js +5 -0
  32. data/app/src/components/audit/entry.js +105 -0
  33. data/app/src/components/audit/fields_mixin.js +11 -0
  34. data/app/src/components/audit/humanize_event.js +213 -0
  35. data/app/src/components/audit/table.js +64 -0
  36. data/app/src/components/audit/table_header.js +37 -0
  37. data/app/src/components/audit/timestamp.js +28 -0
  38. data/app/src/components/auth/login.js +177 -0
  39. data/app/src/components/auth/login.less +71 -0
  40. data/app/src/components/auth/logout.js +42 -0
  41. data/app/src/components/auth/logout.less +21 -0
  42. data/app/src/components/chart/chart.js +540 -0
  43. data/app/src/components/chart/chart_helper_mixin.js +78 -0
  44. data/app/src/components/custom/list.js +3 -0
  45. data/app/src/components/custom/view.js +81 -0
  46. data/app/src/components/dashboard/activity.js +144 -0
  47. data/app/src/components/dashboard/dashboard.js +46 -0
  48. data/app/src/components/flash/flash.js +98 -0
  49. data/app/src/components/flash/flash.less +3 -0
  50. data/app/src/components/generic/__tests__/time-test.js +42 -0
  51. data/app/src/components/generic/annotations.js +39 -0
  52. data/app/src/components/generic/breadcrumbs.js +57 -0
  53. data/app/src/components/generic/foldable_audit_section.js +204 -0
  54. data/app/src/components/generic/list.js +141 -0
  55. data/app/src/components/generic/list_factory.js +41 -0
  56. data/app/src/components/generic/resource_link.js +64 -0
  57. data/app/src/components/generic/role_link.js +66 -0
  58. data/app/src/components/generic/tab_mixin.js +146 -0
  59. data/app/src/components/generic/time.js +32 -0
  60. data/app/src/components/graph/__tests__/collapse-test.js +133 -0
  61. data/app/src/components/graph/__tests__/edges-from-vertices-test.js +48 -0
  62. data/app/src/components/graph/__tests__/new-vertex-set-test.js +16 -0
  63. data/app/src/components/graph/__tests__/next-id-test.js +27 -0
  64. data/app/src/components/graph/__tests__/role-kind-from-id-test.js +24 -0
  65. data/app/src/components/graph/__tests__/vertices-from-edges-test.js +72 -0
  66. data/app/src/components/graph/graph.js +449 -0
  67. data/app/src/components/graph/graph.less +39 -0
  68. data/app/src/components/graph/helpers.js +368 -0
  69. data/app/src/components/group/list.js +3 -0
  70. data/app/src/components/group/view.js +153 -0
  71. data/app/src/components/host/activity.js +111 -0
  72. data/app/src/components/host/details.js +28 -0
  73. data/app/src/components/host/executors.js +77 -0
  74. data/app/src/components/host/host_link.js +18 -0
  75. data/app/src/components/host/list.js +3 -0
  76. data/app/src/components/host/updaters.js +77 -0
  77. data/app/src/components/host/view.js +145 -0
  78. data/app/src/components/layer/list.js +3 -0
  79. data/app/src/components/layer/view.js +197 -0
  80. data/app/src/components/navbar/__tests__/navbar-test.js +21 -0
  81. data/app/src/components/navbar/nav_search_form.js +40 -0
  82. data/app/src/components/navbar/navbar.js +96 -0
  83. data/app/src/components/notfound/notfound.js +35 -0
  84. data/app/src/components/notfound/notfound.less +21 -0
  85. data/app/src/components/owned_resources/owned_resources.js +84 -0
  86. data/app/src/components/owned_resources/owned_resources_box.js +101 -0
  87. data/app/src/components/permissions/permissions.js +138 -0
  88. data/app/src/components/permissions/permissions_table.js +101 -0
  89. data/app/src/components/policy/list.js +3 -0
  90. data/app/src/components/policy/view.js +107 -0
  91. data/app/src/components/refresh/refresh.js +29 -0
  92. data/app/src/components/refresh/refresh.less +15 -0
  93. data/app/src/components/search/group.js +43 -0
  94. data/app/src/components/search/group_heading.js +50 -0
  95. data/app/src/components/search/group_title.js +37 -0
  96. data/app/src/components/search/result_item.js +55 -0
  97. data/app/src/components/search/search.js +118 -0
  98. data/app/src/components/user/activity.js +112 -0
  99. data/app/src/components/user/details.js +30 -0
  100. data/app/src/components/user/list.js +3 -0
  101. data/app/src/components/user/pubkeys.js +118 -0
  102. data/app/src/components/user/pubkeys.less +56 -0
  103. data/app/src/components/user/view.js +143 -0
  104. data/app/src/components/variable/activity.js +101 -0
  105. data/app/src/components/variable/details.js +46 -0
  106. data/app/src/components/variable/fetchers.js +77 -0
  107. data/app/src/components/variable/list.js +3 -0
  108. data/app/src/components/variable/updaters.js +77 -0
  109. data/app/src/components/variable/view.js +115 -0
  110. data/app/src/constants.js +36 -0
  111. data/{public → app/src}/images/conjur-logo.svg +0 -0
  112. data/{public → app/src}/images/icon-client-pc.svg +0 -0
  113. data/{public → app/src}/images/icon-environment.png +0 -0
  114. data/{public → app/src}/images/icon-person.svg +0 -0
  115. data/{public → app/src}/images/icon-policy.png +0 -0
  116. data/{public → app/src}/images/icon-resource.png +0 -0
  117. data/{public → app/src}/images/icon-service-dots.svg +0 -0
  118. data/{public → app/src}/images/icon-variable.png +0 -0
  119. data/app/src/pages/index.html +27 -0
  120. data/app/src/routes.js +64 -0
  121. data/app/src/stores/app_store.js +35 -0
  122. data/app/src/stores/audit_store.js +143 -0
  123. data/app/src/stores/graph_store.js +51 -0
  124. data/app/src/stores/group_store.js +104 -0
  125. data/app/src/stores/host_store.js +111 -0
  126. data/app/src/stores/layer_store.js +115 -0
  127. data/app/src/stores/policy_store.js +88 -0
  128. data/app/src/stores/resources_store.js +115 -0
  129. data/app/src/stores/route_store.js +21 -0
  130. data/app/src/stores/search_store.js +77 -0
  131. data/app/src/stores/user_store.js +109 -0
  132. data/app/src/stores/variable_store.js +93 -0
  133. data/app/src/styles/bootstrap.less +54 -0
  134. data/{public/css → app/src/styles}/styles.less +26 -82
  135. data/app/src/utils.js +38 -0
  136. data/app/src/vendor/pace.js +2 -0
  137. data/conjur-asset-ui.gemspec +3 -4
  138. data/docker/assets-build/Dockerfile +12 -0
  139. data/docker/conjur-ui/Dockerfile +33 -0
  140. data/docker/conjur-ui/README.md +38 -0
  141. data/docker/conjur-ui/mime.types +90 -0
  142. data/docker/conjur-ui/nginx.conf +110 -0
  143. data/docker/conjur-ui/start.py +72 -0
  144. data/docker/conjur-ui/start.sh +18 -0
  145. data/docker/conjur-ui/test.env +8 -0
  146. data/lib/conjur-asset-ui-version.rb +1 -1
  147. data/lib/conjur/command/ui.rb +10 -2
  148. data/lib/conjur/webserver/home.rb +3 -3
  149. data/lib/conjur/webserver/login.rb +1 -1
  150. data/lib/conjur/webserver/server.rb +16 -4
  151. data/public/js/views/roleGraph.js +91 -0
  152. metadata +167 -105
  153. data/.jshintrc +0 -41
  154. data/bower.json +0 -98
  155. data/gulpfile.js +0 -139
  156. data/package.json +0 -47
  157. data/preprocessor.js +0 -7
  158. data/public/_client_libs.html +0 -9
  159. data/public/index.html.erb +0 -63
  160. data/public/js/init.js +0 -196
  161. data/public/js/lib/pace.js +0 -2
  162. data/public/js/lib/sorted-set.no-require.js +0 -1145
  163. data/public/js/lib/sorted-set.no-require.js.txt +0 -6
  164. data/public/js/models/groupRecord.js +0 -72
  165. data/public/js/models/hostRecord.js +0 -60
  166. data/public/js/models/layerRecord.js +0 -79
  167. data/public/js/models/namespace.js +0 -12
  168. data/public/js/models/policyList.js +0 -16
  169. data/public/js/models/policyRecord.js +0 -54
  170. data/public/js/models/record.js +0 -117
  171. data/public/js/models/resourceList.js +0 -87
  172. data/public/js/models/userList.js +0 -25
  173. data/public/js/models/userRecord.js +0 -75
  174. data/public/js/models/variableList.js +0 -27
  175. data/public/js/models/variableRecord.js +0 -77
  176. data/public/js/routers.js +0 -242
  177. data/public/js/views/annotations.js +0 -47
  178. data/public/js/views/audit.js +0 -369
  179. data/public/js/views/breadcrumbs.js +0 -62
  180. data/public/js/views/chart.js +0 -617
  181. data/public/js/views/dashboard.js +0 -146
  182. data/public/js/views/generic.js +0 -122
  183. data/public/js/views/group.js +0 -109
  184. data/public/js/views/groups.js +0 -26
  185. data/public/js/views/host.js +0 -200
  186. data/public/js/views/hosts.js +0 -26
  187. data/public/js/views/layer.js +0 -146
  188. data/public/js/views/layers.js +0 -26
  189. data/public/js/views/mixins/search.js +0 -22
  190. data/public/js/views/mixins/tabs.js +0 -154
  191. data/public/js/views/namespaces.js +0 -40
  192. data/public/js/views/navSearch.js +0 -36
  193. data/public/js/views/owned.js +0 -184
  194. data/public/js/views/permissions.js +0 -254
  195. data/public/js/views/policies.js +0 -26
  196. data/public/js/views/policy.js +0 -70
  197. data/public/js/views/resource.js +0 -59
  198. data/public/js/views/role.js +0 -63
  199. data/public/js/views/searchResults.js +0 -212
  200. data/public/js/views/sections.js +0 -226
  201. data/public/js/views/time.js +0 -39
  202. data/public/js/views/user.js +0 -297
  203. data/public/js/views/users.js +0 -26
  204. data/public/js/views/variable.js +0 -310
  205. data/public/js/views/variables.js +0 -26
  206. data/spec/javascripts/helpers/.gitkeep +0 -0
  207. data/spec/javascripts/support/jasmine.yml +0 -112
  208. data/spec/javascripts/support/jasmine_helper.rb +0 -22
  209. data/spec/javascripts/support/run.html.erb +0 -23
  210. data/spec/javascripts/views/AuditSpec.js +0 -22
  211. data/spec/javascripts/views/AuditSpec.ls +0 -18
@@ -1,26 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, React */
3
-
4
- (function(conjur, React) {
5
- 'use strict';
6
-
7
- var GenericList = conjur.views.GenericList;
8
-
9
- this.HostBox = React.createClass({
10
- render: function() {
11
- return (
12
- <div className="hostBox">
13
- <div className="hostList">
14
- <h2>Hosts</h2>
15
- <GenericList data={{kind: 'hosts', members: this.props.data.members}} />
16
- </div>
17
- </div>
18
- );
19
- }
20
- });
21
-
22
- }).bind(conjur.views)
23
- (
24
- conjur,
25
- React
26
- );
@@ -1,146 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, React, ReactBootstrap, _ */
3
-
4
- (function(conjur, React, ReactBootstrap, _) {
5
- 'use strict';
6
-
7
- var TabbedArea = ReactBootstrap.TabbedArea,
8
- TabPane = ReactBootstrap.TabPane,
9
- Tab = conjur.views.mixins.Tab,
10
- AuditBox = window.AuditBox,
11
- Breadcrumbs = conjur.views.Breadcrumbs,
12
- RoleLink = conjur.views.RoleLink,
13
- HostLink = conjur.views.HostLink;
14
-
15
- var abstractRole = function(expected) {
16
- return function(role) {
17
- var tokens = role.split(':'),
18
- kind = tokens[1],
19
- abstractKinds = ['@', 'layer'],
20
- isAbstract = abstractKinds.indexOf(kind) !== -1;
21
-
22
- return isAbstract === expected;
23
- };
24
- };
25
-
26
- this.Layer = React.createClass({
27
- mixins: [Tab],
28
-
29
- render: function() {
30
- var data = this.props.data;
31
-
32
- var hosts = data.layer.hosts.map(function(host) {
33
- return (
34
- <li className="list-group-item list-group-item-noborder">
35
- <HostLink data={host} />
36
- </li>
37
- );
38
- });
39
-
40
- var admins = data.admins.filter(abstractRole(false)).map(function(role) {
41
- return (
42
- <li className="list-group-item list-group-item-noborder">
43
- <RoleLink id={role}/>
44
- </li>
45
- );
46
- });
47
-
48
- var users = data.users.filter(abstractRole(false)).map(function(role) {
49
- return (
50
- <li className="list-group-item list-group-item-noborder">
51
- <RoleLink id={role}/>
52
- </li>
53
- );
54
- });
55
-
56
- // TODO: controls to add/remove admins/users/hosts
57
- var overviewTab = (
58
- <TabPane key="overview" tab="Overview">
59
- <dl className="dl-horizontal">
60
- <dt>Owner</dt>
61
- <dd><RoleLink id={data.owner} /></dd>
62
-
63
- <dt>Created by</dt>
64
- <dd><RoleLink id={data.layer.userid} /></dd>
65
- </dl>
66
- </TabPane>
67
- );
68
-
69
- var adminsTab = (
70
- <TabPane key="admins" tab={conjur.utils.getTabname('Admins', admins)}>
71
- <ul className="list-group">
72
- {admins}
73
- </ul>
74
- </TabPane>
75
- );
76
-
77
- var usersTab = (
78
- <TabPane key="users" tab={conjur.utils.getTabname('Users', users)}>
79
- <ul className="list-group">
80
- {users}
81
- </ul>
82
- </TabPane>
83
- );
84
-
85
- var hostsTab = (
86
- <TabPane key="hosts" tab={conjur.utils.getTabname('Hosts', hosts)}>
87
- <ul className="list-group">
88
- {hosts}
89
- </ul>
90
- </TabPane>
91
- );
92
-
93
- var auditTab = (
94
- <TabPane key="audit" tab="Recent Activity">
95
- <div className="audit auditGroup">
96
- <AuditBox roles={[data.layer.roleid]}
97
- resources={[data.layer.resource_identifier]}
98
- tabview={true} />
99
- </div>
100
- </TabPane>
101
- );
102
-
103
-
104
- var permissionsTab = this.permissionsTab(data.layer.roleid),
105
- membershipsTab = this.membershipsTab(data.layer.roleid),
106
- annotationsTab = this.annotationsTab(),
107
- ownedTab = this.ownedTab();
108
-
109
- var tabs = _.compact([
110
- overviewTab,
111
- adminsTab,
112
- usersTab,
113
- hostsTab,
114
- ownedTab,
115
- membershipsTab,
116
- permissionsTab,
117
- annotationsTab,
118
- auditTab
119
- ]);
120
-
121
- var elems = [
122
- {url: '/ui/layers', text: 'Layers'},
123
- {url: '', text: this.props.data.layer.id},
124
- {url: '', text: '(owned by ' + this.props.data.layer.ownerid + ')'}
125
- ];
126
-
127
- return (
128
- <div className="b-layer">
129
- <Breadcrumbs elems={elems} />
130
- <hr />
131
- <h2>Layer {data.layer.id}</h2>
132
- <TabbedArea defaultActiveKey="overview">
133
- {tabs}
134
- </TabbedArea>
135
- </div>
136
- );
137
- }
138
- });
139
-
140
- }).bind(conjur.views)
141
- (
142
- conjur,
143
- React,
144
- ReactBootstrap,
145
- _
146
- );
@@ -1,26 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, React */
3
-
4
- (function(conjur, React) {
5
- 'use strict';
6
-
7
- var GenericList = conjur.views.GenericList;
8
-
9
- this.LayerBox = React.createClass({
10
- render: function() {
11
- return (
12
- <div className="layerBox">
13
- <div className="layerList">
14
- <h2>Layers</h2>
15
- <GenericList data={{kind: 'layers', members: this.props.data.members}} />
16
- </div>
17
- </div>
18
- );
19
- }
20
- });
21
-
22
- }).bind(conjur.views)
23
- (
24
- conjur,
25
- React
26
- );
@@ -1,22 +0,0 @@
1
- /* global conjur */
2
-
3
- (function(conjur) {
4
- 'use strict';
5
-
6
- this.Search = {
7
- handleSubmit: function() {
8
- var search = this.refs.input.getDOMNode().value;
9
-
10
- if (search && search.length !== 0) {
11
- conjur.app.router.navigate('/ui/search/' + window.encodeURIComponent(search),
12
- {trigger: true});
13
- }
14
-
15
- return false;
16
- }
17
- };
18
-
19
- }).bind(conjur.views.mixins)
20
- (
21
- conjur
22
- );
@@ -1,154 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, React, ReactBootstrap, _ */
3
-
4
- (function(conjur, React, ReactBootstrap, _) {
5
- 'use strict';
6
-
7
- var TabPane = ReactBootstrap.TabPane,
8
- OwnedResources = conjur.views.OwnedResources,
9
- RoleLink = conjur.views.RoleLink,
10
- AnnotationsBox = conjur.views.AnnotationsBox,
11
- Permissions = conjur.views.Permissions;
12
-
13
- // we can't create custom TabPanes as components,
14
- // because they won't be recognized by TabbedArea as tabs
15
- // that's why we just generalize their constructors
16
- this.Tab = {
17
- containsOwnedItems: function() {
18
- return (
19
- this.props.data.owned &&
20
- this.props.data.owned.length &&
21
- this.props.data.owned.length > 0
22
- );
23
- },
24
-
25
- ownedIds: function() {
26
- if (this.containsOwnedItems()) {
27
- return this.props.data.owned.map(function(ownedItem) {
28
- return ownedItem.id;
29
- });
30
- }
31
-
32
- return [];
33
- },
34
-
35
- ownedTab: function() {
36
- if (this.containsOwnedItems()) {
37
- var result = (
38
- <TabPane key="owned"
39
- tab={conjur.utils.getTabname('Owned resources', this.props.data.owned)}>
40
- <OwnedResources owned={this.props.data.owned} tabview={true} />
41
- </TabPane>
42
- );
43
-
44
- return result;
45
- }
46
-
47
- return null;
48
- },
49
-
50
- containsNontrivialRoles: function() {
51
- return (
52
- this.props.data.roles &&
53
- this.props.data.roles.length &&
54
- this.props.data.roles.length > 1
55
- );
56
- },
57
-
58
- externalRoles: function(ownId) {
59
- if (!this.containsNontrivialRoles()) {
60
- return [];
61
- }
62
-
63
- var ownedIds = this.ownedIds();
64
-
65
- return this.props.data.roles.filter(function(roleid) {
66
- // do not show themself
67
- return roleid !== ownId;
68
- }).filter(function(roleid) {
69
- // do not show internal roles
70
- return roleid.split(':')[1] !== '@';
71
- }).filter(function(roleid) {
72
- // do not show owned groups
73
- return ! _.contains(ownedIds, roleid);
74
- });
75
- },
76
-
77
- membershipsTab: function(ownId) {
78
- if (!this.containsNontrivialRoles()) {
79
- return null;
80
- }
81
-
82
- var membershipLinks = this.externalRoles(ownId)
83
- .sort(function(a, b) {
84
- return a.toLowerCase().localeCompare(b.toLowerCase());
85
- })
86
- .map(function(roleid) {
87
- return (
88
- <li className="list-group-item list-group-item-noborder">
89
- <RoleLink id={roleid} />
90
- </li>
91
- );
92
- });
93
-
94
- if (membershipLinks.length === 0) {
95
- return null;
96
- }
97
-
98
- var result = (
99
- <TabPane key="memberships"
100
- tab={conjur.utils.getTabname('Explicit memberships', membershipLinks)}>
101
- <ul className="list-group">
102
- {membershipLinks}
103
- </ul>
104
- </TabPane>
105
- );
106
-
107
- return result;
108
- },
109
-
110
- containsAnnotations: function() {
111
- return (
112
- this.props.data.annotations &&
113
- this.props.data.annotations.length &&
114
- this.props.data.annotations.length > 0
115
- );
116
- },
117
-
118
- annotationsTab: function() {
119
- if (!this.containsAnnotations()) {
120
- return null;
121
- }
122
-
123
- var result = (
124
- <TabPane key="annotations"
125
- tab={conjur.utils.getTabname('Annotations', this.props.data.annotations)}>
126
- <AnnotationsBox annotations={this.props.data.annotations} />
127
- </TabPane>
128
- );
129
-
130
- return result;
131
- },
132
-
133
- permissionsTab: function(roleid) {
134
- var result = (
135
- <TabPane key="permissions" tab="Permissions held">
136
- <Permissions owned={this.props.data.owned}
137
- roles={this.props.data.roles}
138
- role={roleid}
139
- tabview={true} />
140
- </TabPane>
141
- );
142
-
143
- return result;
144
- }
145
-
146
- };
147
-
148
- }).bind(conjur.views.mixins)
149
- (
150
- conjur,
151
- React,
152
- ReactBootstrap,
153
- _
154
- );
@@ -1,40 +0,0 @@
1
- /** @jsx React.DOM */
2
-
3
- var NamespaceFilter = React.createClass({
4
- render: function() {
5
- return(
6
- <div className="namespaceList">
7
- <h2>Namespace filter:</h2>
8
- { this.transferPropsTo(<NamespaceList />) }
9
- </div>
10
- );
11
- }
12
- });
13
-
14
- var NamespaceListItem = React.createClass({
15
- render: function() {
16
- return (
17
- <option value={this.props.id}>{this.props.id}</option>
18
- );
19
- }
20
- });
21
-
22
- var NamespaceList = React.createClass({
23
- handleChange: function(e) {
24
- var value = e.target.options[e.target.selectedIndex].value;
25
- updateNamespace(value);
26
- },
27
- render: function() {
28
- var namespaces = this.props.namespaces.map(function (namespace) {
29
- return <NamespaceListItem id={namespace}/>;
30
- }).sort();
31
- return (
32
- <div>
33
- <select onChange={this.handleChange} value={this.props.currentNamespace}>
34
- <option value="" />
35
- {namespaces}
36
- </select>
37
- </div>
38
- );
39
- }
40
- });
@@ -1,36 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, React */
3
-
4
- (function(conjur, React) {
5
- 'use strict';
6
-
7
- var Search = conjur.views.mixins.Search;
8
-
9
- this.NavSearchForm = React.createClass({
10
- mixins: [Search],
11
-
12
- render: function() {
13
- return (
14
- <form className="form-inline navbar-form"
15
- role="search"
16
- onSubmit={this.handleSubmit}>
17
- <div className="form-group">
18
- <input ref="input"
19
- type="text"
20
- className="form-control"
21
- placeholder="Search Conjur"></input>
22
- </div>
23
- <button type="submit"
24
- className="btn btn-default search-button">
25
- Search
26
- </button>
27
- </form>
28
- );
29
- }
30
- });
31
-
32
- }).bind(conjur.views)
33
- (
34
- conjur,
35
- React
36
- );