Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: web/inc/logdog-list-view/logdog-list-view.html

Issue 2991253003: [logdog] Replace list view with query view. (Closed)
Patch Set: handle enter for submit Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « web/inc/apps/logdog-app/main.ts ('k') | web/inc/logdog-query-view/logdog-query-panel.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <!--
2 Copyright 2016 The LUCI Authors. All rights reserved.
3 Use of this source code is governed under the Apache License, Version 2.0
4 that can be found in the LICENSE file.
5 -->
6
7 <link rel="import" href="../bower_components/polymer/polymer.html">
8 <link rel="import" href="../bower_components/iron-icon/iron-icon.html">
9 <link rel="import" href="../bower_components/paper-material/paper-material.html" >
10 <link rel="import" href="../logdog-styles/app-theme.html">
11 <link rel="import" href="../rpc/rpc-client.html">
12 <link rel="import" href="../logdog-stream/logdog-stream.html">
13
14
15 <!--
16 This element is the paging component, allowing a user to navigate through
17 list offsets.
18
19 It is constructed as a separate element because it is repeated both above and
20 below the actual list.
21
22 This has two "offset" concepts: the bound requested offset is the offset that
23 is bound to the "logdog-list-view" RPC offset parameter. The display offset
24 is the offset that the latest list refresh used.
25
26 These are distinguished because we want the user's intent to change offset
27 (e.g., tap) event to immediately change the offset, but we don't want the
28 rendered offsets to actually update until the next set of list elements has
29 been loaded and rendered.
30 -->
31 <dom-module id="logdog-list-view-paging">
32
33 <style is="custom-style">
34 #nav {
35 padding: 4px 4px 4px 4px;
36 margin: 10px 0px 10px 0px;
37 }
38
39 a {
40 border-style: solid;
41 border-color: lightgray;
42 border-width: 1px;
43 user-select: none;
44 margin: 8px;
45 padding: 4px 4px 4px 4px;
46 cursor: pointer;
47 }
48 </style>
49
50 <template>
51 <div id="nav">
52 <!-- "Back to the beginning" zero button -->
53 <template is="dom-if" if="[[_hasValue(_links.zero)]]">
54 <a on-click="_loadOffset"
55 data-args$="{{ _links.zero }}">
56 [[_links.zero]]
57 </a>
58 </template>
59
60 <!-- Previous page button -->
61 <template is="dom-if" if="[[_hasValue(_links.prev)]]">
62 <a on-click="_loadOffset"
63 data-args$="{{ _links.prev }}">
64 &lt; [[_links.prev]]
65 </a>
66 </template>
67
68 <!-- Next page button -->
69 <template is="dom-if" if="[[_hasValue(_links.next)]]">
70 <a on-click="_loadOffset"
71 data-args$="{{ _links.next }}">
72 [[_links.next]] &gt;
73 </a>
74 </template>
75 </div>
76 </template>
77
78 </dom-module>
79
80 <script>
81 "use strict";
82
83 Polymer({
84 is: 'logdog-list-view-paging',
85 properties: {
86 /**
87 * The request-bound offset parameter. This is changed when a button is
88 * clicked.
89 */
90 offset: {
91 type: Number,
92 value: 0,
93 notify: true,
94 },
95
96 /** The offset of the currently-rendered list. Used to generate links. */
97 displayOffset: {
98 type: Number,
99 value: 0,
100 notify: true,
101 },
102
103 /** True if there is at least one more page after the current one. */
104 hasMore: {
105 type: Boolean,
106 notify: true,
107 },
108
109 /** The offset increment amount */
110 size: {
111 type: Number,
112 value: 0,
113 notify: true,
114 },
115
116 /** A dictionary with the current zero, prev, and next offset values. */
117 _links: {
118 computed: '_computeLinks(displayOffset, size, hasMore)',
119 },
120 },
121
122 /**
123 * Computed function which rebuilds the links when any parameters change.
124 */
125 _computeLinks: function(offset, size, hasMore) {
126 return {
127 next: (hasMore) ? (offset + size) : null,
128 prev: (offset > size) ? (offset - size) : null,
129 zero: (offset > 0) ? (0) : null,
130 };
131 },
132
133 /** Filter function to test if a given value is not null. */
134 _hasValue: function(v) {
135 return (v !== null);
136 },
137
138 /** Loads the offset from a nav button into the "offset" parameter. */
139 _loadOffset: function(e) {
140 this.offset = parseInt(e.currentTarget.dataset.args || "0");
141 },
142 });
143 </script>
144
145 <!--
146 An element for fetching complete LogDog log streams.
147 -->
148 <dom-module id="logdog-list-view">
149
150 <style>
151 #components {
152 background-color: var(--nav-background-color);
153 padding: 4px 4px 4px 4px;
154 margin: 4px 4px 4px 4px;
155 }
156 #components a {
157 color: var(--primary-text-color);
158 text-decoration: none;
159 }
160 #components ul {
161 padding: 0;
162 margin: 0;
163 }
164 #components li {
165 display: inline;
166 }
167 #components paper-material {
168 padding: 4px 4px 4px 4px;
169 margin-left: 4px;
170 margin-right: 4px;
171 display: inline-block;
172 background-color: var(--nav-item-color);
173 }
174
175 #list {
176 text-decoration: none;
177 width: 90%;
178 margin: 10px 10px 10px 10px;
179 }
180 #list a {
181 color: var(--primary-text-color);
182 text-decoration: none;
183 }
184 #list ul {
185 padding: 0;
186 margin: 0;
187 list-style-type: none;
188 border-width: 1px;
189 border-color: darkgray;
190 border-style: solid;
191 }
192 #list li {
193 padding: 2px 2px 2px 2px;
194 margin: 5px 10px 5px 10px;
195 font-size: 1.1em;
196 }
197 #list li a {
198 display: block;
199 }
200 #list li:nth-of-type(odd) {
201 background-color: white;
202 }
203 #list li:nth-of-type(even) {
204 background-color: #f2f2f2;
205 }
206 #list .stream-component {
207 font-weight: bold;
208 }
209 </style>
210
211 <template>
212 <!-- Load server description -->
213 <rpc-client
214 id="client"
215 auto-token
216 host="[[host]]"
217 service="logdog.Logs"
218 method="List"
219 request="[[_body]]"
220 last-response="{{lastResponse}}"></rpc-client>
221
222 <!--
223 The current set of components. For example, for "foo/bar/+/baz", this
224 expands into:
225
226 [foo] [bar] [+] [baz]
227 -->
228 <div id="components">
229 <ul>
230 <template is="dom-repeat" items="[[components]]">
231 <li>
232 <paper-material elevation="1">
233 <a href="[[linkBase]][[item.path]]">[[item.name]]</a>
234 </paper-material>
235 </li>
236 </template>
237 </ul>
238 </div>
239
240 <!-- Prev/Next links (top) -->
241 <logdog-list-view-paging
242 base="[[base]]"
243 offset="{{offset}}"
244 display-offset="[[currentOffset]]"
245 has-more="[[_hasMore]]"
246 size="[[count]]">
247 </logdog-list-view-paging>
248
249 <!-- The current list view. -->
250 <div id="list" flex>
251 <ul>
252 <!-- Sub-paths (directories) -->
253 <template is="dom-repeat" items="[[paths]]">
254 <li class="path-component">
255 <a href="[[linkBase]][[item.full]]">
256 [[item.value]]
257 </a>
258 </li>
259 </template>
260
261 <!-- Stream contents (files) -->
262 <template is="dom-repeat" items="[[streams]]">
263 <li class="stream-component">
264 <a href="[[streamLinkBase]]?s=[[item.full]]">
265 [[item.value]]
266 </a>
267 </li>
268 </template>
269 </ul>
270 </div>
271
272 <!-- Prev/Next links (bottom) -->
273 <logdog-list-view-paging
274 base="[[base]]"
275 offset="{{offset}}"
276 display-offset="[[currentOffset]]"
277 has-more="[[_hasMore]]"
278 size="[[count]]">
279 </logdog-list-view-paging>
280 </template>
281
282 </dom-module>
283
284 <script>
285 Polymer({
286 is: "logdog-list-view",
287 properties: {
288
289 hostAttributes: {
290 hidden: true,
291 },
292
293 /** The name ([host][:port]) of the pRPC host. */
294 host: {
295 type: String,
296 notify: true,
297 },
298
299 /** Generated path links will have this prepended to them. */
300 linkBase: {
301 type: String,
302 value: "",
303 notify: true,
304 },
305
306 /**
307 * Generated stream links will use this parameter, referencing the
308 * selected streams with "s" query parameters.
309 */
310 streamLinkBase: {
311 type: String,
312 notify: true,
313 },
314
315 /**
316 * The current log list base.
317 *
318 * Base is a unified "project/path..." string. If empty, the list will be
319 * project-level.
320 */
321 base: {
322 type: Object,
323 value: "",
324 notify: true,
325 },
326
327 /** The maximum number of list elements to request. */
328 count: {
329 type: Number,
330 value: 50,
331 notify: true,
332 },
333
334 /** The list request offset. */
335 offset: {
336 type: Number,
337 value: 0,
338 notify: true,
339 },
340
341 /** The path components under "base". */
342 paths: {
343 type: Array,
344 value: function() {
345 return [];
346 },
347 readOnly: true,
348 },
349
350 /** The stream components under "base". */
351 streams: {
352 type: Array,
353 value: [],
354 readOnly: true,
355 },
356
357 /**
358 * Split "base" into components (e.g., "foo/bar" => [foo, foo/bar])
359 * for navigation.
360 */
361 components: {
362 type: Array,
363 value: [],
364 readOnly: true,
365 },
366
367 /**
368 * The "next" cursor value from the latest response.
369 *
370 * This will be null if there is no next cursor value.
371 */
372 nextPage: {
373 type: String,
374 value: null,
375 readOnly: true,
376 },
377
378 /** The offset of the current list. */
379 currentOffset: {
380 type: Number,
381 value: 0,
382 readOnly: true,
383 },
384
385 _body: {
386 computed: "_computeBody(base, count, offset)",
387 },
388
389 /** True if the latest request specified additional pages. */
390 _hasMore: {
391 computed: "_computeHasMore(nextPage)",
392 },
393
394 lastResponse: {
395 type: Object,
396 observer: '_onLastResponseChanged',
397 },
398 },
399
400 observers: [
401 "_hostChanged(host, base)",
402 "_baseChanged(base)",
403 ],
404
405 /** Called when the host value has changed. Reset. */
406 _hostChanged: function(host, base) {
407 if (host !== this.host) {
408 this.base = "/";
409 this._resetOffset();
410 }
411
412 // Enable automatic request sending once our "host" has loaded. */
413 this.$.client.auto = (!!this.host);
414 },
415
416 /** Called when the base value has changed. */
417 _baseChanged: function(base) {
418 this._resetOffset();
419 },
420
421 /** Reset offset parameters. */
422 _resetOffset: function() {
423 this.offset = 0;
424 this._setCurrentOffset(0);
425 },
426
427 /**
428 * Returns true if there are additional list results. We know this if the
429 * latest response supplied a non-empty "next" cursor value.
430 */
431 _computeHasMore: function(nextPage) {
432 return (!!nextPage);
433 },
434
435 _computeBody: function(base, count, offset) {
436 var req = {
437 "maxResults": count,
438 "offset": offset,
439 };
440
441 // Split our base into project and path.
442 var lds = LogDogStream.splitProject(base);
443 req.project = lds.project;
444 req.pathBase = lds.path;
445 return req;
446 },
447
448 _onLastResponseChanged: function(resp) {
449 this._setNextPage(resp.next);
450 this._setCurrentOffset(this.offset);
451
452 // Calculate our unified path base (project/path...).
453 var components = [];
454 if (resp.project) {
455 components.push(resp.project);
456
457 if (resp.pathBase) {
458 components.push.apply(components, resp.pathBase.split("/"));
459 }
460 }
461
462 // Calculate partial components.
463 if (components.length && components[0] === "") {
464 // Remove the initial "/" element. It will be forcefully inserted at the
465 // end.
466 components.shift();
467 }
468
469 // Generate our individual components.
470 this.base = components.join("/");
471 components = components.map(function(cur, idx, arr) {
472 return {
473 name: cur,
474 path: arr.slice(0, idx+1).join("/"),
475 };
476 });
477 components.unshift({
478 name: "/",
479 path: "",
480 });
481 this._setComponents(components);
482
483 // Calculate path components.
484 this._setPaths((resp.components || []).filter(function(e) {
485 return (e.type !== "STREAM");
486 }).map(function(e) {
487 var full = e.name;
488 if (this.base !== "") {
489 full = this.base + "/" + full;
490 }
491 return {
492 value: e.name,
493 full: full,
494 };
495 }.bind(this)));
496
497 // Calculate stream components.
498 this._setStreams((resp.components || []).filter(function(e) {
499 return (e.type === "STREAM");
500 }).map(function(e) {
501 var full = e.name;
502 if (resp.base !== "") {
503 full = this.base + "/" + full;
504 };
505 return {
506 value: e.name,
507 full: full,
508 };
509 }.bind(this)));
510 },
511 });
512 </script>
OLDNEW
« no previous file with comments | « web/inc/apps/logdog-app/main.ts ('k') | web/inc/logdog-query-view/logdog-query-panel.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698