Implement list-view-behavior

Even though a gr-list-view element has been established for many of the
common list view functions, The tables themselves are still
generated by the parent element and passed as <content>.  There were
many common functions used in the table generation itself.

Break out those common functions into a behavior, and implement in
gr-admin-group-list and gr-admin-project list. This will be used in
further admin pages as well.

Change-Id: I60227b8c30ac18176bbf923ee1fb02bdd985e5c3
This commit is contained in:
Becky Siegel
2017-06-09 14:39:15 -07:00
parent 5cc5a45919
commit e00d1eeede
8 changed files with 176 additions and 69 deletions

View File

@@ -0,0 +1,55 @@
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../base-url-behavior/base-url-behavior.html">
<link rel="import" href="../gr-url-encoding-behavior.html">
<script>
(function(window) {
'use strict';
/** @polymerBehavior Gerrit.ListViewBehavior */
const ListViewBehavior = {
computeLoadingClass(loading) {
return loading ? 'loading' : '';
},
computeShownItems(items) {
return items.slice(0, 25);
},
getUrl(path, item) {
return this.getBaseUrl() + path + this.encodeURL(item, true);
},
getFilterValue(params) {
if (!params) { return null; }
return this._filter = params.filter || null;
},
getOffsetValue(params) {
if (params && params.offset) {
return params.offset;
}
return 0;
},
};
window.Gerrit = window.Gerrit || {};
window.Gerrit.ListViewBehavior = [
ListViewBehavior,
window.Gerrit.BaseUrlBehavior,
window.Gerrit.URLEncodingBehavior];
})(window);
</script>

View File

@@ -0,0 +1,89 @@
<!DOCTYPE html>
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
<script src="../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-list-view-behavior.html">
<test-fixture id="basic">
<template>
<test-element></test-element>
</template>
</test-fixture>
<script>
suite('gr-list-view-behavior tests', () => {
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.ListViewBehavior],
});
});
setup(() => {
element = fixture('basic');
});
test('computeLoadingClass', () => {
assert.equal(element.computeLoadingClass(true), 'loading');
assert.equal(element.computeLoadingClass(false), '');
});
test('computeShownItems', () => {
const myArr = new Array(26);
assert.equal(element.computeShownItems(myArr).length, 25);
});
test('getUrl', () => {
assert.equal(element.getUrl('/path/to/something/', 'item'),
'/path/to/something/item');
assert.equal(element.getUrl('/path/to/something/', 'item%test'),
'/path/to/something/item%2525test');
});
test('getFilterValue', () => {
let params;
assert.equal(element.getFilterValue(params), null);
params = {filter: null};
assert.equal(element.getFilterValue(params), null);
params = {filter: 'test'};
assert.equal(element.getFilterValue(params), 'test');
});
test('getOffsetValue', () => {
let params;
assert.equal(element.getOffsetValue(params), 0);
params = {offset: null};
assert.equal(element.getOffsetValue(params), 0);
params = {offset: 1};
assert.equal(element.getOffsetValue(params), 1);
});
});
</script>

View File

@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior.html">
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-list-view/gr-list-view.html">
@@ -39,14 +38,14 @@ limitations under the License.
<th class="description topHeader">Group Description</th>
<th class="visibleToAll topHeader">Visible To All</th>
</tr>
<tr id="loading" class$="loadingMsg [[_computeLoadingClass(_loading)]]">
<tr id="loading" class$="loadingMsg [[computeLoadingClass(_loading)]]">
<td>Loading...</td>
</tr>
<template is="dom-repeat" items="[[_shownGroups]]"
class$="[[_computeLoadingClass(_loading)]]">
class$="[[computeLoadingClass(_loading)]]">
<tr class="table">
<td class="name">
<a href$="[[_getUrl(item.group_id)]]">[[item.name]]</a>
<a href$="[[getUrl(path, item.group_id)]]">[[item.name]]</a>
</td>
<td class="description">[[item.description]]</td>
<td class="visibleToAll">[[_visibleToAll(item)]]</td>

View File

@@ -30,7 +30,11 @@
* Offset of currently visible query results.
*/
_offset: Number,
_path: {
type: String,
readOnly: true,
value: '/admin/groups/',
},
_groups: Array,
/**
@@ -39,7 +43,7 @@
* */
_shownGroups: {
type: Array,
computed: '_computeShownGroups(_groups)',
computed: 'computeShownItems(_groups)',
},
_groupsPerPage: {
@@ -55,8 +59,7 @@
},
behaviors: [
Gerrit.BaseUrlBehavior,
Gerrit.URLEncodingBehavior,
Gerrit.ListViewBehavior,
],
listeners: {
@@ -64,18 +67,11 @@
'previous-page': '_handlePreviousPage',
},
_paramsChanged(value) {
_paramsChanged(params) {
this._loading = true;
this._filter = this.getFilterValue(params);
this._offset = this.getOffsetValue(params);
if (value) {
this._filter = value.filter || null;
}
if (value && value.offset) {
this._offset = value.offset;
} else {
this._offset = 0;
}
return this._getGroups(this._filter, this._groupsPerPage,
this._offset);
},
@@ -97,21 +93,8 @@
});
},
_computeLoadingClass(loading) {
return loading ? 'loading' : '';
},
_visibleToAll(item) {
return item.options.visible_to_all === true ? 'Y' : 'N';
},
_getUrl(item) {
return this.getBaseUrl() + '/admin/groups/' +
this.encodeURL(item, true);
},
_computeShownGroups(groups) {
return groups.slice(0, 25);
},
});
})();

View File

@@ -130,14 +130,14 @@ limitations under the License.
suite('loading', () => {
test('correct contents are displayed', () => {
assert.isTrue(element._loading);
assert.equal(element._computeLoadingClass(element._loading), 'loading');
assert.equal(element.computeLoadingClass(element._loading), 'loading');
assert.equal(getComputedStyle(element.$.loading).display, 'block');
element._loading = false;
element._groups = _.times(25, groupGenerator);
flushAsynchronousOperations();
assert.equal(element._computeLoadingClass(element._loading), '');
assert.equal(element.computeLoadingClass(element._loading), '');
assert.equal(getComputedStyle(element.$.loading).display, 'none');
});
});

View File

@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior.html">
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-list-view/gr-list-view.html">
@@ -41,14 +40,14 @@ limitations under the License.
<th class="repositoryBrowser topHeader">Repository Browser</th>
<th class="readOnly topHeader">Read only</th>
</tr>
<tr id="loading" class$="loadingMsg [[_computeLoadingClass(_loading)]]">
<tr id="loading" class$="loadingMsg [[computeLoadingClass(_loading)]]">
<td>Loading...</td>
</tr>
<template is="dom-repeat" items="[[_shownProjects]]"
class$="[[_computeLoadingClass(_loading)]]">
class$="[[computeLoadingClass(_loading)]]">
<tr class="table">
<td class="name">
<a href$="[[_getUrl(item.name)]]">[[item.name]]</a>
<a href$="[[getUrl(path, item.name)]]">[[item.name]]</a>
</td>
<td class="description">[[item.description]]</td>
<td class="repositoryBrowser">

View File

@@ -30,7 +30,11 @@
* Offset of currently visible query results.
*/
_offset: Number,
_path: {
type: String,
readOnly: true,
value: '/admin/projects/',
},
_projects: Array,
/**
@@ -39,7 +43,7 @@
* */
_shownProjects: {
type: Array,
computed: '_computeShownProjects(_projects)',
computed: 'computeShownItems(_projects)',
},
_projectsPerPage: {
@@ -55,22 +59,13 @@
},
behaviors: [
Gerrit.BaseUrlBehavior,
Gerrit.URLEncodingBehavior,
Gerrit.ListViewBehavior,
],
_paramsChanged(value) {
_paramsChanged(params) {
this._loading = true;
if (value) {
this._filter = value.filter || null;
}
if (value && value.offset) {
this._offset = value.offset;
} else {
this._offset = 0;
}
this._filter = this.getFilterValue(params);
this._offset = this.getOffsetValue(params);
return this._getProjects(this._filter, this._projectsPerPage,
this._offset);
@@ -93,19 +88,10 @@
});
},
_computeLoadingClass(loading) {
return loading ? 'loading' : '';
},
_readOnly(item) {
return item.state === 'READ_ONLY' ? 'Y' : 'N';
},
_getUrl(item) {
return this.getBaseUrl() + '/admin/projects/' +
this.encodeURL(item, true);
},
_computeWeblink(project) {
if (!project.web_links) {
return '';
@@ -113,9 +99,5 @@
const webLinks = project.web_links;
return webLinks.length ? webLinks : null;
},
_computeShownProjects(projects) {
return projects.slice(0, 25);
},
});
})();

View File

@@ -125,14 +125,14 @@ limitations under the License.
suite('loading', () => {
test('correct contents are displayed', () => {
assert.isTrue(element._loading);
assert.equal(element._computeLoadingClass(element._loading), 'loading');
assert.equal(element.computeLoadingClass(element._loading), 'loading');
assert.equal(getComputedStyle(element.$.loading).display, 'block');
element._loading = false;
element._projects = _.times(25, projectGenerator);
flushAsynchronousOperations();
assert.equal(element._computeLoadingClass(element._loading), '');
assert.equal(element.computeLoadingClass(element._loading), '');
assert.equal(getComputedStyle(element.$.loading).display, 'none');
});
});