##// END OF EJS Templates
search: added narrow result links for global search.
marcink -
r3467:36ee2e14 default
parent child Browse files
Show More
@@ -1,285 +1,291 b''
1 1 // summary.less
2 2 // For use in RhodeCode applications;
3 3 // Used for headers and file detail summary screens.
4 4
5 5 .summary {
6 6 float: left;
7 7 position: relative;
8 8 width: 100%;
9 9 margin: 0;
10 10 padding: 0;
11 11
12 12 .summary-detail-header {
13 13 float: left;
14 14 display: block;
15 15 width: 100%;
16 16 margin-bottom: @textmargin;
17 17 padding: 0 0 .5em 0;
18 18 border-bottom: @border-thickness solid @border-default-color;
19 19
20 20 .breadcrumbs {
21 21 float: left;
22 22 display: inline;
23 23 margin: 0;
24 24 padding: 0;
25 25 }
26 26 h4 {
27 27 float: left;
28 28 margin: 0 1em 0 0;
29 29 padding: 0;
30 30 line-height: 1.2em;
31 31 font-size: @basefontsize;
32 32 }
33 33
34 34 .action_link {
35 35 float: right;
36 36 }
37 37
38 38 .new-file {
39 39 float: right;
40 40 margin-top: -1.5em;
41 41 }
42 42 }
43 43
44 44 .summary-detail {
45 45 float: left;
46 46 position: relative;
47 47 width: 73%;
48 48 margin: 0 3% @space 0;
49 49 padding: 0;
50 50
51 51 .file_diff_buttons {
52 52 margin-top: @space;
53 53 }
54 54
55 55 // commit message
56 56 .commit {
57 57 white-space: pre-wrap;
58 58 }
59 59
60 60 .left-clone {
61 61 float: left;
62 62 height: 30px;
63 63 margin: 0;
64 64 padding: 0;
65 65 font-weight: @text-semibold-weight;
66 66 font-family: @text-semibold;
67 67 }
68 68
69 69 .right-clone {
70 70 float: right;
71 71 width: 83%;
72 72 }
73 73
74 74 .clone_url_input {
75 75 width: ~"calc(100% - 35px)";
76 76 padding: 5px;
77 77 }
78 78
79 79 &.directory {
80 80 margin-bottom: 0;
81 81 }
82 82
83 83 .desc {
84 84 white-space: pre-wrap;
85 85 }
86 86 .disabled {
87 87 opacity: .5;
88 88 cursor: inherit;
89 89 }
90 90 .help-block {
91 91 color: inherit;
92 92 margin: 0;
93 93 }
94 94 }
95 95
96 96 .sidebar-right {
97 97 float: left;
98 98 width: 24%;
99 99 margin: 0;
100 100 padding: 0;
101 101
102 102 ul {
103 103 margin-left: 0;
104 104 padding-left: 0;
105 105
106 106 li {
107 107 list-style-type: none;
108 108 }
109 109 }
110 110 }
111 111
112 112 #clone_by_name, #clone_by_id{
113 113 display: inline-block;
114 114 margin-left: 0px;
115 115 }
116 116
117 117 .codeblock {
118 118 border: none;
119 119 background-color: transparent;
120 120 }
121 121
122 122 .code-body {
123 123 border: @border-thickness solid @border-default-color;
124 124 .border-radius(@border-radius);
125 125 }
126 126 }
127 127
128 128 // this is used outside of just the summary
129 129 .fieldset, // similar to form fieldset
130 130 .summary .sidebar-right-content { // these have to match
131 131 clear: both;
132 132 float: left;
133 133 position: relative;
134 134 display:block;
135 135 width: 100%;
136 136 min-height: 1em;
137 137 margin-bottom: @textmargin;
138 138 padding: 0;
139 139 line-height: 1.2em;
140 140
141 141 &:after { // clearfix
142 142 content: "";
143 143 clear: both;
144 144 width: 100%;
145 145 height: 1em;
146 146 }
147 147 }
148 148
149 149 .summary .sidebar-right-content {
150 150 margin-bottom: @space;
151 151
152 152 .rc-user {
153 153 min-width: 0;
154 154 }
155 155 }
156 156
157 157 .fieldset {
158 158
159 159 .left-label { // similar to form legend
160 160 float: left;
161 161 display: block;
162 162 width: 25%;
163 163 margin: 0;
164 164 padding: 0;
165 165 font-weight: @text-semibold-weight;
166 166 font-family: @text-semibold;
167 167 }
168 168
169 169 .left-label-summary {
170 170 .left-label;
171 171 width: 150px;
172 172 }
173 173
174 174 .right-content { // similar to form fields
175 175 float: left;
176 176 display: block;
177 177 width: 75%;
178 178 margin: 0 0 0 -15%;
179 179 padding: 0 0 0 15%;
180 180
181 181 .truncate-wrap,
182 182 .truncate {
183 183 max-width: 100%;
184 184 width: 100%;
185 185 }
186 186
187 187 .commit-long {
188 188 overflow-x: auto;
189 189 }
190 190 }
191 191 .commit.truncate-wrap {
192 192 overflow:hidden;
193 193 text-overflow: ellipsis;
194 194 }
195 195 }
196 196
197 197 // expand commit message
198 198 #message_expand {
199 199 clear: both;
200 200 display: block;
201 201 color: @rcblue;
202 202 cursor: pointer;
203 203 }
204 204
205 205 #trimmed_message_box {
206 206 max-height: floor(2 * @basefontsize * 1.2); // 2 lines * line-height
207 207 overflow: hidden;
208 208 }
209 209
210 210 // show/hide comments button
211 211 .show-inline-comments {
212 212 display: inline;
213 213 cursor: pointer;
214 214
215 215 .comments-show { display: inline; }
216 216 .comments-hide { display: none; }
217 217
218 218 &.comments-visible {
219 219 .comments-show { display: none; }
220 220 .comments-hide { display: inline; }
221 221 }
222 222 }
223 223
224 224 // Quick Start section
225 225 .quick_start {
226 226 float: left;
227 227 display: block;
228 228 position: relative;
229 229 width: 100%;
230 230
231 231 // adds some space to make copy and paste easier
232 232 .left-label,
233 233 .right-content {
234 234 line-height: 1.6em;
235 235 }
236 236 }
237 237
238 238 .submodule {
239 239 .summary-detail {
240 240 width: 100%;
241 241
242 242 .btn-collapse {
243 243 display: none;
244 244 }
245 245 }
246 246 }
247 247
248 248 .codeblock-header {
249 249 float: left;
250 250 display: block;
251 251 width: 100%;
252 252 margin: 0;
253 253 padding: @space 0 10px 0;
254 254 border-top: @border-thickness solid @border-default-color;
255 255
256 256 .stats {
257 257 float: left;
258 258 }
259 259 .stats-filename {
260 260 font-size: 120%;
261 261 }
262 262 .stats-first-item {
263 263 padding: 0px 0px 0px 3px;
264 264 }
265 265
266 266 .buttons {
267 267 float: right;
268 268 text-align: right;
269 269 color: @grey4;
270 270 }
271
272 .file-container {
273 display: inline-block;
274 width: 100%;
275 }
276
271 277 }
272 278
273 279 #summary-menu-stats {
274 280
275 281 .stats-bullet {
276 282 color: @grey3;
277 283 min-width: 3em;
278 284 }
279 285
280 286 .repo-size {
281 287 margin-bottom: .5em;
282 288 }
283 289
284 290 }
285 291
@@ -1,214 +1,222 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 %if c.repo_name:
6 6 ${_('Search inside repository {repo_name}').format(repo_name=c.repo_name)}
7 7 %elif c.repo_group_name:
8 8 ${_('Search inside repository group {repo_group_name}').format(repo_group_name=c.repo_group_name)}
9 9 %else:
10 10 ${_('Search inside all accessible repositories')}
11 11 %endif
12 12 %if c.rhodecode_name:
13 13 &middot; ${h.branding(c.rhodecode_name)}
14 14 %endif
15 15 </%def>
16 16
17 17 <%def name="breadcrumbs_links()">
18 18 %if c.repo_name:
19 19 ${_('Search inside repository {repo_name}').format(repo_name=c.repo_name)}
20 20 %elif c.repo_group_name:
21 21 ${_('Search inside repository group {repo_group_name}').format(repo_group_name=c.repo_group_name)}
22 22 %else:
23 23 ${_('Search inside all accessible repositories')}
24 24 %endif
25 25
26 26 </%def>
27 27
28 28 <%def name="menu_bar_nav()">
29 29 %if c.repo_name:
30 30 ${self.menu_items(active='search')}
31 31 %elif c.repo_group_name:
32 32 ${self.menu_items(active='search')}
33 33 %else:
34 34 ${self.menu_items(active='search')}
35 35 %endif
36 36 </%def>
37 37
38 38 <%def name="menu_bar_subnav()">
39 39 %if c.repo_name:
40 40 ${self.repo_menu(active='search')}
41 41 %elif c.repo_group_name:
42 42 ${self.repo_group_menu(active='search')}
43 43 %endif
44 44 </%def>
45 45
46 <%def name="repo_icon(db_repo)">
47 %if h.is_hg(db_repo):
48 <i class="icon-hg"></i>
49 %endif
50 %if h.is_git(db_repo):
51 <i class="icon-git"></i>
52 %endif
53 %if h.is_svn(db_repo):
54 <i class="icon-svn"></i>
55 %endif
56 </%def>
57
58 <%def name="repo_group_icon()">
59 <i class="icon-folder-close"></i>
60 </%def>
61
46 62 <%def name="main()">
47 63 <div class="box">
48 64 %if c.repo_name:
49 65 <!-- box / title -->
50 66 <div class="title">
51 67 ${self.repo_page_title(c.rhodecode_db_repo)}
52 68 </div>
53 69 ${h.form(h.route_path('search_repo',repo_name=c.repo_name),method='get')}
54 70 %elif c.repo_group_name:
55 71 <!-- box / title -->
56 72 <div class="title">
57 73 ${self.repo_group_page_title(c.repo_group)}
58 74 </div>
59 75 ${h.form(h.route_path('search_repo_group',repo_group_name=c.repo_group_name),method='get')}
60 76 %else:
61 77 <!-- box / title -->
62 78 <div class="title">
63 79 ${self.breadcrumbs()}
64 80 <ul class="links">&nbsp;</ul>
65 81 </div>
66 82 <!-- end box / title -->
67 83 ${h.form(h.route_path('search'), method='get')}
68 84 %endif
69 85 <div class="form search-form">
70 86 <div class="fields">
71 87
72 88 ${h.text('q', c.cur_query, placeholder="Enter query...")}
73 89
74 90 ${h.select('type',c.search_type,[('content',_('Files')), ('path',_('File path')),('commit',_('Commits'))],id='id_search_type')}
75 91 ${h.hidden('max_lines', '10')}
76 92
77 93 <input type="submit" value="${_('Search')}" class="btn"/>
78 94 <br/>
79 95
80 96 <div class="search-tags">
81 97 <span class="tag tag8">
82 98 %if c.repo_name:
83 <a href="${h.route_path('search', _query={'q': c.cur_query})}">${_('Global Search')}</a>
99 <a href="${h.route_path('search', _query={'q': c.cur_query, 'type': request.GET.get('type', 'content')})}">${_('Global Search')}</a>
84 100 %elif c.repo_group_name:
85 <a href="${h.route_path('search', _query={'q': c.cur_query})}">${_('Global Search')}</a>
101 <a href="${h.route_path('search', _query={'q': c.cur_query, 'type': request.GET.get('type', 'content')})}">${_('Global Search')}</a>
86 102 % else:
87 103 ${_('Global Search')}
88 104 %endif
89 105 </span>
90 106
91 107 %if c.repo_name:
92 108 Β»
93 109 <span class="tag tag8">
94 %if h.is_hg(c.rhodecode_db_repo):
95 <i class="icon-hg"></i>
96 %endif
97 %if h.is_git(c.rhodecode_db_repo):
98 <i class="icon-git"></i>
99 %endif
100 %if h.is_svn(c.rhodecode_db_repo):
101 <i class="icon-svn"></i>
102 %endif
110 ${repo_icon(c.rhodecode_db_repo)}
103 111 ${c.repo_name}
104 112 </span>
105 113
106 114 %elif c.repo_group_name:
107 115 Β»
108 116 <span class="tag tag8">
109 <i class="icon-folder-close"></i>
117 ${repo_group_icon()}
110 118 ${c.repo_group_name}
111 119 </span>
112 120 %endif
113 121
114 122
115 123 % for search_tag in c.search_tags:
116 124 <br/><span class="tag disabled" style="margin-top: 3px">${search_tag}</span>
117 125 % endfor
118 126
119 127 </div>
120 128
121 129 <div class="search-feedback-items">
122 130 % for error in c.errors:
123 131 <span class="error-message">
124 132 % for k,v in error.asdict().items():
125 133 ${k} - ${v}
126 134 % endfor
127 135 </span>
128 136 % endfor
129 137 <div class="field">
130 138 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Query Langague examples')}</p>
131 139 <pre id="search-help" style="display: none">\
132 140
133 141 % if c.searcher.name == 'whoosh':
134 142 Example filter terms for `Whoosh` search:
135 143 query lang: <a href="${c.searcher.query_lang_doc}">Whoosh Query Language</a>
136 144 Whoosh has limited query capabilities. For advanced search use ElasticSearch 6 from RhodeCode EE edition.
137 145
138 146 Generate wildcards using '*' character:
139 147 "repo_name:vcs*" - search everything starting with 'vcs'
140 148 "repo_name:*vcs*" - search for repository containing 'vcs'
141 149
142 150 Optional AND / OR operators in queries
143 151 "repo_name:vcs OR repo_name:test"
144 152 "owner:test AND repo_name:test*" AND extension:py
145 153
146 154 Move advanced search is available via ElasticSearch6 backend in EE edition.
147 155 % elif c.searcher.name == 'elasticsearch' and c.searcher.es_version == '2':
148 156 Example filter terms for `ElasticSearch-${c.searcher.es_version}`search:
149 157 ElasticSearch-2 has limited query capabilities. For advanced search use ElasticSearch 6 from RhodeCode EE edition.
150 158
151 159 search type: content (File Content)
152 160 indexed fields: content
153 161
154 162 # search for `fix` string in all files
155 163 fix
156 164
157 165 search type: commit (Commit message)
158 166 indexed fields: message
159 167
160 168 search type: path (File name)
161 169 indexed fields: path
162 170
163 171 % else:
164 172 Example filter terms for `ElasticSearch-${c.searcher.es_version}`search:
165 173 query lang: <a href="${c.searcher.query_lang_doc}">ES 6 Query Language</a>
166 174 The reserved characters needed espace by `\`: + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
167 175 % for handler in c.searcher.get_handlers().values():
168 176
169 177 search type: ${handler.search_type_label}
170 178 *indexed fields*: ${', '.join( [('\n ' if x[0]%4==0 else '')+x[1] for x in enumerate(handler.es_6_field_names)])}
171 179 % for entry in handler.es_6_example_queries:
172 180 ${entry.rstrip()}
173 181 % endfor
174 182 % endfor
175 183
176 184 % endif
177 185 </pre>
178 186 </div>
179 187
180 188 <div class="field">${c.runtime}</div>
181 189 </div>
182 190 </div>
183 191 </div>
184 192
185 193 ${h.end_form()}
186 194 <div class="search">
187 195 % if c.search_type == 'content':
188 196 <%include file='search_content.mako'/>
189 197 % elif c.search_type == 'path':
190 198 <%include file='search_path.mako'/>
191 199 % elif c.search_type == 'commit':
192 200 <%include file='search_commit.mako'/>
193 201 % elif c.search_type == 'repository':
194 202 <%include file='search_repository.mako'/>
195 203 % endif
196 204 </div>
197 205 </div>
198 206 <script>
199 207 $(document).ready(function(){
200 208 $("#id_search_type").select2({
201 209 'containerCssClass': "drop-menu",
202 210 'dropdownCssClass': "drop-menu-dropdown",
203 211 'dropdownAutoWidth': true,
204 212 'minimumResultsForSearch': -1
205 213 });
206 214
207 215 $('#q').autoGrowInput({maxWidth: 920});
208 216
209 217 setTimeout(function() {
210 218 $('#q').keyup()
211 219 }, 1);
212 220 })
213 221 </script>
214 222 </%def>
@@ -1,103 +1,98 b''
1 1 <%namespace name="base" file="/base/base.mako"/>
2 <%namespace name="search" file="/search/search.mako"/>
2 3
3 4 % if c.formatted_results:
4 5
5 6 <table class="rctable search-results">
6 7 <tr>
7 8 <th>${_('Repository')}</th>
8 9 <th>${_('Commit')}</th>
9 10 <th></th>
10 11 <th>${_('Commit message')}</th>
11 12 <th>
12 13 %if c.sort == 'newfirst':
13 14 <a href="${c.url_generator(sort='oldfirst')}">${_('Age (new first)')}</a>
14 15 %else:
15 16 <a href="${c.url_generator(sort='newfirst')}">${_('Age (old first)')}</a>
16 17 %endif
17 18 </th>
18 19 <th>${_('Author')}</th>
19 20 </tr>
20 21 %for entry in c.formatted_results:
21 22 ## search results are additionally filtered, and this check is just a safe gate
22 23 % if c.rhodecode_user.is_admin or h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(entry['repository'], 'search results commit check'):
23 24 <tr class="body">
24 25 <td class="td-componentname">
25 26 <% repo_type = entry.get('repo_type') or h.get_repo_type_by_name(entry.get('repository')) %>
26 %if repo_type == 'hg':
27 <i class="icon-hg"></i>
28 %elif repo_type == 'git':
29 <i class="icon-git"></i>
30 %elif repo_type == 'svn':
31 <i class="icon-svn"></i>
32 %endif
27 ${search.repo_icon(repo_type)}
33 28 ${h.link_to(entry['repository'], h.route_path('repo_summary',repo_name=entry['repository']))}
34 29 </td>
35 30 <td class="td-commit">
36 31 ${h.link_to(h._shorten_commit_id(entry['commit_id']),
37 32 h.route_path('repo_commit',repo_name=entry['repository'],commit_id=entry['commit_id']))}
38 33 </td>
39 34 <td class="td-message expand_commit search open" data-commit-id="${h.md5_safe(entry['repository'])+entry['commit_id']}" id="t-${h.md5_safe(entry['repository'])+entry['commit_id']}" title="${_('Expand commit message')}">
40 35 <div>
41 36 <i class="icon-expand-linked"></i>&nbsp;
42 37 </div>
43 38 </td>
44 39 <td data-commit-id="${h.md5_safe(entry['repository'])+entry['commit_id']}" id="c-${h.md5_safe(entry['repository'])+entry['commit_id']}" class="message td-description open">
45 40 %if entry.get('message_hl'):
46 41 ${h.literal(entry['message_hl'])}
47 42 %else:
48 43 ${h.urlify_commit_message(entry['message'], entry['repository'])}
49 44 %endif
50 45 </td>
51 46 <td class="td-time">
52 47 ${h.age_component(h.time_to_utcdatetime(entry['date']))}
53 48 </td>
54 49
55 50 <td class="td-user author">
56 51 <%
57 52 ## es6 stores this as object
58 53 author = entry['author']
59 54 if isinstance(author, dict):
60 55 author = author['email']
61 56 %>
62 57 ${base.gravatar_with_user(author)}
63 58 </td>
64 59 </tr>
65 60 % endif
66 61 %endfor
67 62 </table>
68 63
69 64 %if c.cur_query:
70 65 <div class="pagination-wh pagination-left">
71 66 ${c.formatted_results.pager('$link_previous ~2~ $link_next')}
72 67 </div>
73 68 %endif
74 69
75 70 <script>
76 71 $('.expand_commit').on('click',function(e){
77 72 var target_expand = $(this);
78 73 var cid = target_expand.data('commit-id');
79 74
80 75 if (target_expand.hasClass('open')){
81 76 $('#c-'+cid).css({'height': '1.5em', 'white-space': 'nowrap', 'text-overflow': 'ellipsis', 'overflow':'hidden'});
82 77 $('#t-'+cid).css({'height': 'auto', 'line-height': '.9em', 'text-overflow': 'ellipsis', 'overflow':'hidden'});
83 78 target_expand.removeClass('open');
84 79 }
85 80 else {
86 81 $('#c-'+cid).css({'height': 'auto', 'white-space': 'normal', 'text-overflow': 'initial', 'overflow':'visible'});
87 82 $('#t-'+cid).css({'height': 'auto', 'max-height': 'none', 'text-overflow': 'initial', 'overflow':'visible'});
88 83 target_expand.addClass('open');
89 84 }
90 85 });
91 86
92 87 $(".message.td-description").mark(
93 88 "${c.searcher.query_to_mark(c.cur_query, 'message')}",
94 89 {
95 90 "className": 'match',
96 91 "accuracy": "complementary",
97 92 "ignorePunctuation": ":._(){}[]!'+=".split("")
98 93 }
99 94 );
100 95
101 96 </script>
102 97
103 98 % endif
@@ -1,152 +1,180 b''
1 <%namespace name="search" file="/search/search.mako"/>
1 2
2 3 <%def name="highlight_text_file(has_matched_content, file_content, lexer, html_formatter, matching_lines, shown_matching_lines, url, use_hl_filter)">
3 4 % if has_matched_content:
4 5 ${h.code_highlight(file_content, lexer, html_formatter, use_hl_filter=use_hl_filter)|n}
5 6 % else:
6 7 ${_('No content matched')} <br/>
7 8 % endif
8 9
9 10 %if len(matching_lines) > shown_matching_lines:
10 11 <a href="${url}">
11 12 ${len(matching_lines) - shown_matching_lines} ${_('more matches in this file')}
12 13 </a>
13 14 %endif
14 15 </%def>
15 16
16 17 <div class="search-results">
17 18 <% query_mark = c.searcher.query_to_mark(c.cur_query, 'content') %>
18 19
19 20 %for entry in c.formatted_results:
20 21
21 22 <%
22 23 file_content = entry['content_highlight'] or entry['content']
23 24 mimetype = entry.get('mimetype')
24 25 filepath = entry.get('path')
25 26 max_lines = h.safe_int(request.GET.get('max_lines', '10'))
26 27 line_context = h.safe_int(request.GET.get('line_contenxt', '3'))
27 28
28 29 match_file_url=h.route_path('repo_files',repo_name=entry['repository'], commit_id=entry.get('commit_id', 'tip'),f_path=entry['f_path'], _query={"mark": query_mark})
29 30 terms = c.cur_query
30 31
31 32 if c.searcher.is_es_6:
32 33 # use empty terms so we default to markers usage
33 34 total_lines, matching_lines = h.get_matching_line_offsets(file_content, terms=None)
34 35 else:
35 36 total_lines, matching_lines = h.get_matching_line_offsets(file_content, terms)
36 37
37 38 shown_matching_lines = 0
38 39 lines_of_interest = set()
39 40 for line_number in matching_lines:
40 41 if len(lines_of_interest) < max_lines:
41 42 lines_of_interest |= set(range(
42 43 max(line_number - line_context, 0),
43 44 min(line_number + line_context, total_lines + 1)))
44 45 shown_matching_lines += 1
45 46 lexer = h.get_lexer_safe(mimetype=mimetype, filepath=filepath)
46 47
47 48 html_formatter = h.SearchContentCodeHtmlFormatter(
48 49 linenos=True,
49 50 cssclass="code-highlight",
50 51 url=match_file_url,
51 52 query_terms=terms,
52 53 only_line_numbers=lines_of_interest
53 54 )
54 55
55 56 has_matched_content = len(lines_of_interest) >= 1
56 57
57 58 %>
58 59 ## search results are additionally filtered, and this check is just a safe gate
59 60 % if c.rhodecode_user.is_admin or h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(entry['repository'], 'search results content check'):
60 61 <div id="codeblock" class="codeblock">
61 62 <div class="codeblock-header">
62 63 <h1>
63 64 <% repo_type = entry.get('repo_type') or h.get_repo_type_by_name(entry.get('repository')) %>
64 %if repo_type == 'hg':
65 <i class="icon-hg"></i>
66 %elif repo_type == 'git':
67 <i class="icon-git"></i>
68 %elif repo_type == 'svn':
69 <i class="icon-svn"></i>
70 %endif
65 ${search.repo_icon(repo_type)}
71 66 ${h.link_to(entry['repository'], h.route_path('repo_summary',repo_name=entry['repository']))}
72 67 </h1>
73
74 <div class="stats">
75 <span class="stats-filename">
76 <strong>
77 <i class="icon-file-text"></i>
78 ${h.link_to(h.literal(entry['f_path']), h.route_path('repo_files',repo_name=entry['repository'],commit_id=entry.get('commit_id', 'tip'),f_path=entry['f_path']))}
79 </strong>
80 </span>
81 <span class="item last"><i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${entry['f_path']}" title="${_('Copy the full path')}"></i></span>
82 <br/>
83 <span class="stats-first-item">
84 ${len(matching_lines)} ${_ungettext('search match', 'search matches', len(matching_lines))}
85 </span>
68 ## level 1
69 <div class="file-container">
86 70
87 <span >
88 %if entry.get('lines'):
89 | ${entry.get('lines', 0.)} ${_ungettext('line', 'lines', entry.get('lines', 0.))}
90 %endif
91 </span>
71 <div class="pull-left">
72 <span class="stats-filename">
73 <strong>
74 <i class="icon-file-text"></i>
75 ${h.link_to(h.literal(entry['f_path']), h.route_path('repo_files',repo_name=entry['repository'],commit_id=entry.get('commit_id', 'tip'),f_path=entry['f_path']))}
76 </strong>
77 </span>
78 <span class="item last">
79 <i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${entry['f_path']}" title="${_('Copy the full path')}"></i>
80 </span>
81 </div>
92 82
93 <span>
94 %if entry.get('size'):
95 | ${h.format_byte_size_binary(entry['size'])}
96 %endif
97 </span>
98
99 <span>
100 %if entry.get('mimetype'):
101 | ${entry.get('mimetype', "unknown mimetype")}
102 %endif
103 </span>
83 <div class="pull-right">
84 <div class="buttons">
85 <a id="file_history_overview_full" href="${h.route_path('repo_changelog_file',repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path',''))}">
86 ${_('Show Full History')}
87 </a>
88 | ${h.link_to(_('Annotation'), h.route_path('repo_files:annotated', repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
89 | ${h.link_to(_('Raw'), h.route_path('repo_file_raw', repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
90 | ${h.link_to(_('Download'), h.route_path('repo_file_download',repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
91 </div>
92 </div>
104 93
105 94 </div>
106 <div class="buttons">
107 <a id="file_history_overview_full" href="${h.route_path('repo_changelog_file',repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path',''))}">
108 ${_('Show Full History')}
109 </a>
110 | ${h.link_to(_('Annotation'), h.route_path('repo_files:annotated', repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
111 | ${h.link_to(_('Raw'), h.route_path('repo_file_raw', repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
112 | ${h.link_to(_('Download'), h.route_path('repo_file_download',repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
95 ## level 2
96 <div class="file-container">
97
98 <div class="pull-left">
99 <span class="stats-first-item">
100 %if entry.get('lines'):
101 ${entry.get('lines', 0.)} ${_ungettext('line', 'lines', entry.get('lines', 0.))}
102 (${len(matching_lines)} ${_ungettext('matched', 'matched', len(matching_lines))})
103 %endif
104 </span>
105
106 <span>
107 %if entry.get('size'):
108 | ${h.format_byte_size_binary(entry['size'])}
109 %endif
110 </span>
111
112 <span>
113 %if entry.get('mimetype'):
114 | ${entry.get('mimetype', "unknown mimetype")}
115 %endif
116 </span>
117 </div>
118
119 <div class="pull-right">
120 <div class="search-tags">
121
122 <% repo_group = entry.get('repository_group')%>
123 ## hiden if in repo group view
124 % if repo_group and not c.repo_group_name:
125 <span class="tag tag8">
126 ${search.repo_group_icon()}
127 <a href="${h.route_path('search_repo_group', repo_group_name=repo_group, _query={'q': c.cur_query})}">${_('Narrow to this repository group')}</a>
128 </span>
129 % endif
130 ## hiden if in repo view
131 % if not c.repo_name:
132 <span class="tag tag8">
133 ${search.repo_icon(repo_type)}
134 <a href="${h.route_path('search_repo', repo_name=entry.get('repo_name'), _query={'q': c.cur_query})}">${_('Narrow to this repository')}</a>
135 </span>
136 % endif
137 </div>
138 </div>
139
113 140 </div>
141
114 142 </div>
115 143 <div class="code-body search-code-body">
116 144
117 145 ${highlight_text_file(
118 146 has_matched_content=has_matched_content,
119 147 file_content=file_content,
120 148 lexer=lexer,
121 149 html_formatter=html_formatter,
122 150 matching_lines=matching_lines,
123 151 shown_matching_lines=shown_matching_lines,
124 152 url=match_file_url,
125 153 use_hl_filter=c.searcher.is_es_6
126 154 )}
127 155 </div>
128 156
129 157 </div>
130 158 % endif
131 159 %endfor
132 160 </div>
133 161 %if c.cur_query and c.formatted_results:
134 162 <div class="pagination-wh pagination-left" >
135 163 ${c.formatted_results.pager('$link_previous ~2~ $link_next')}
136 164 </div>
137 165 %endif
138 166
139 167 %if c.cur_query:
140 168 <script type="text/javascript">
141 169 $(function(){
142 170 $(".search-code-body").mark(
143 171 "${query_mark}",
144 172 {
145 173 "className": 'match',
146 174 "accuracy": "complementary",
147 175 "ignorePunctuation": ":._(){}[]!'+=".split("")
148 176 }
149 177 );
150 178 })
151 179 </script>
152 180 %endif
@@ -1,50 +1,46 b''
1 <%namespace name="search" file="/search/search.mako"/>
2
1 3 % if c.formatted_results:
2 4
3 5 <table class="rctable search-results">
4 6 <tr>
5 7 <th>${_('Repository')}</th>
6 8 <th>${_('File')}</th>
7 9 <th>${_('Size')}</th>
8 10 <th>${_('Lines')}</th>
9 11 </tr>
10 12 %for entry in c.formatted_results:
11 13 ## search results are additionally filtered, and this check is just a safe gate
12 14 % if c.rhodecode_user.is_admin or h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(entry['repository'], 'search results path check'):
13 15 <tr class="body">
14 16 <td class="td-componentname">
15 17 <% repo_type = entry.get('repo_type') or h.get_repo_type_by_name(entry.get('repository')) %>
16 %if repo_type == 'hg':
17 <i class="icon-hg"></i>
18 %elif repo_type == 'git':
19 <i class="icon-git"></i>
20 %elif repo_type == 'svn':
21 <i class="icon-svn"></i>
22 %endif
18 ${search.repo_icon(repo_type)}
23 19 ${h.link_to(entry['repository'], h.route_path('repo_summary',repo_name=entry['repository']))}
24 20 </td>
25 21 <td class="td-componentname">
26 22 ${h.link_to(h.literal(entry['f_path']),
27 23 h.route_path('repo_files',repo_name=entry['repository'],commit_id='tip',f_path=entry['f_path']))}
28 24 </td>
29 25 <td>
30 26 %if entry.get('size'):
31 27 ${h.format_byte_size_binary(entry['size'])}
32 28 %endif
33 29 </td>
34 30 <td>
35 31 %if entry.get('lines'):
36 32 ${entry.get('lines', 0.)} ${_ungettext('line', 'lines', entry.get('lines', 0.))}
37 33 %endif
38 34 </td>
39 35 </tr>
40 36 % endif
41 37 %endfor
42 38 </table>
43 39
44 40 %if c.cur_query:
45 41 <div class="pagination-wh pagination-left">
46 42 ${c.formatted_results.pager('$link_previous ~2~ $link_next')}
47 43 </div>
48 44 %endif
49 45
50 46 % endif
General Comments 0
You need to be logged in to leave comments. Login now